【问题标题】:Reduce all values to one specified将所有值减少到指定的值
【发布时间】:2015-04-19 21:56:22
【问题描述】:

所以我有一组列表,如下所示:

[['Amy,1,"10,10,6"'], ['Bella,3,"4,7,2"'], ['Cendrick,3,"5,1,9"'], ['Fella,2,"3,8,4"'], ['Hussain,1,"9,4,3"'], ['Jamie,2,"1,1,1"'], ['Jack,3,"10,8,0"'], ['Thomas,2,"5,0,5"'], ['Zyra,1,"7,8,7"']]

其中姓名后面的数字是学生的班级编号,后面的3个数字是该学生得分的3个分数。

我已将它从一组有组织的列表中排序到按字母顺序排列的列表中,但是我在以下方面遇到了困难:

我希望能够按字母顺序对它们进行排序,但仅针对特定班级和最后三个值中的最高分。例如,如果我想对第 2 类进行排序,那么输出将如下所示:

Fella,8
Jamie,1
Thomas,5

由于姓名已按字母顺序排序,所有学生都来自第 2 班。每个学生的高分也放在他们旁边。

我非常感谢任何帮助。 TIA

【问题讨论】:

    标签: sorting python-3.x


    【解决方案1】:

    您的数据结构很差。看起来您想将每个学生的信息保存在一个列表中,但最终只在该列表中放置了一个带有该信息的逗号分隔字符串。然后你得到了一个列表列表,每个列表都包含一个这样的字符串。

    这确实是你想做的:

    [[Amy, 1, 10,10,6],
     [Bella, 3, 4,7,2],
     [Cendrick, 3, 5,1,9],
     [Fella, 2, 3,8,4],
     [Hussain, 1, 9,4,3],
     [Jamie, 2, 1,1,1],
     [Jack, 3, 10,8,0],
     [Thomas, 2, 5,0,5],
     [Zyra, 1, 7,8,7]
    ]
    

    以下是你如何将你拥有的东西变成你想要的东西:

    students = []
    
    for student in myList:  # myList is the list that you already have
        s = []
        name, course, grades = student[0].split(',', 2)
        s.append(name)
        s.append(int(course))
        s.extend([int(i) for i in grades.strip('"').split(',')])
        students.append(s)
    

    一旦你有了这个,你就可以对students进行过滤和排序,如下所示:

    import operator
    classNum = 1  # let's say you want all the students from class number 1
    answer = sorted([s for s in students if s[1]==classNum], key=operator.itemgetter(0))
    
    for student in answer:
        name = student[0]
        grade = max(student[2:]))
        print(name, grade)
    

    请注意,我说过这似乎是您想要做的。在你的位置上,我会这样做:

    from collections import namedtuple as ntuple
    
    Student = ntuple('Student', ['name', 'course', 'grades'])
    students = []
    
    courseNum = 1
    for student in myList:  # myList is the list that you already have
        s = Student
        name, course, grades = student[0].split(',', 2)
        course = int(course)
        if course != courseNum: continue
        grades = [int(i) for i in grades.strip('"').split(',')]
        students.append(Student(name, course, grades))
    
    students.sort(key=operator.attrgetter('name'))
    for student in students:
        print(student.name, max(student.grades))
    

    【讨论】:

    • 无论哪种方式,我都会遇到相同的错误。它说有太多的值需要解压,因为它期望 3 在名称、课程、成绩 = 学生 [0]...
    • @Hussain:很抱歉。我错过了那里的一个微妙的错误。立即尝试
    • 非常感谢兄弟,现在似乎工作正常,非常感谢您的帮助
    • @Hussain:请标记已接受的答案,以便其他用户知道您的问题已得到解答
    • ValueError: need more than 1 value to unpack, 我又遇到了同样的错误,而且它发生在同一个位置 - name, course, grades = student[0]...抱歉打扰了,但是你能解决这个问题并向我解释当我得到这个“值解包”错误时它意味着什么。 TIA。
    【解决方案2】:

    也许这会起作用:

    def transform(inputs, class_number):
      results = []
      for input in inputs:
        input = input[0]
        input_pieces = input.split(',', 2)
        if input_pieces[1] != class_number:
          continue
        scores = input_pieces[2].strip('"').split(',')
        results.append((input_pieces[0], max(scores)))
      return results
    

    另外,我强烈建议您使用一些东西来为您的数据提供更多的结构,而不仅仅是逗号分隔的字符串。像collections.namedtuple 这样的东西。然后你可以有一个命名元组的列表,其中包含有意义的命名字段。

    【讨论】:

    • 我没有注意到每个元素都是一个字符串。我编辑了我的解决方案。
    • 转换函数中的“输入”是什么意思 - 当我调用函数时,我应该把列表的名称放在这里吗?
    • 是的,你通过了列表。
    • 我在函数的返回点不断收到语法错误
    【解决方案3】:

    以下是解决方案,使用您目前存储数据的方式 - 使处理变得困难。

    >>> lst = [['Amy,1,"10,10,6"'], ['Bella,3,"4,7,2"'], ['Cendrick,3,"5,1,9"'],
     ['Fella,2,"3,8,4"'], ['Hussain,1,"9,4,3"'], ['Jamie,2,"1,1,1"'], ['Jack,3,"10,8,0"'], ['Thomas,2,"5,0,5"'], ['Zyra,1,"7,8,7"']]
    
    >>> from itertools import chain
    >>> lst_flat = chain.from_iterable(lst)
    >>> sorted_lst = sorted(filter(lambda x: x.split(',')[1] == '2', lst_flat))
    >>> print map(lambda x: (x.split(',')[0],
                  max([int(y) for y in x.split('"')[1].split(',')])), sorted_lst)
    
    [('Fella', 8), ('Jamie', 1), ('Thomas', 5)]
    

    您应该考虑清理您表示数据的方式:

    >>> from pprint import pprint
    >>> from itertools import chain
    
    >>> lst_clean = []
    >>> for item in chain.from_iterable(lst):
        ... name, cls = item.split(',')[0], item.split(',')[1]
        ... marks = [int(x) for x in item.split('"')[1].split(',')]
        ... lst_clean.append((name, cls, marks))
    
    >>> pprint(lst_clean)
    
    [('Amy', '1', [10, 10, 6]),
    ('Bella', '3', [4, 7, 2]),
    ('Cendrick', '3', [5, 1, 9]),
    ('Fella', '2', [3, 8, 4]),
    ('Hussain', '1', [9, 4, 3]),
    ('Jamie', '2', [1, 1, 1]),
    ('Jack', '3', [10, 8, 0]),
    ('Thomas', '2', [5, 0, 5]),
    ('Zyra', '1', [7, 8, 7])]
    
    >>> sorted_lst = sorted([(name, cls, marks) for (name, cls, marks) in lst_clean if cls == '2'])
    >>> for name, cls, marks in sorted_lst:
        ... print name, max(marks)
    
    Fella 8
    Jamie 1
    Thomas 5
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-01
      • 1970-01-01
      • 2013-04-15
      • 2021-07-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多