社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

在python中处理嵌入在字典列表中的元组列表

tsb • 4 年前 • 951 次点击  

我在一个初级的编码类,我似乎无法把我所教的基本知识变成一个工作程序,一个如此复杂的列表。我应该使用什么函数来执行此操作?

在这一点上,我们还没有讨论导入任何额外的特性(numpy等),我知道人们经常使用lambda(虽然我不太了解它的功能),但这一点在这个类中还没有介绍。

#This is an example of the structure of a student dictionary
#They have an id number
#They have a first name, last name and a list of assignments
#Assignments are tuples of an assignment name and grade
#The grade is a 4 point scale from 0 to 4
'''
student_list = [{'id': 12341, 'first_name': 'Alice', 'last_name': 'Anderson',
     'assignments': [('assignment_1', 0), ('assignment_2', 2), ('assignment_3', 4)]},

 {'id': 12342, 'first_name': 'Boris', 'last_name': 'Bank',
   'assignments': [('assignment_1', 1), ('assignment_2', 3), ('assignment_3', 0)]},

 {'id': 12343, 'first_name': 'Carl', 'last_name': 'Cape',
   'assignments': [('assignment_1', 2), ('assignment_2', 4), ('assignment_3', 1)]},

 {'id': 12344, 'first_name': 'Didi', 'last_name': 'Dawson',
   'assignments': [('assignment_1', 3), ('assignment_2', 0), ('assignment_3', 2)]},

 {'id': 12345, 'first_name': 'Ed', 'last_name': 'Enders',
   'assignments': [('assignment_1', 4), ('assignment_2', 1), ('assignment_3', 3)]}]

#This function should return a list of the n student dictionaries with the
#highest grades on the assignment passed in as assignment name
#If there is a tie then it is broken by returning the student(s) with the
#lowest id number(s)
def highest_n_grades(students, assignment_name, n):

编辑

我希望能在正确的方向上找到一个点,比如什么样的命令可以获得最高的成绩等等。到目前为止,我真正拥有的是:

def highest_n_grades(student_list):
  for s in student_list:
    for assignment_name, grade in s['assignments']:
        if int(grade) >= 4:
            print(assignment_name, grade)

highest_n_grades(student_list)

编辑2

我也试过了,但是我试着对字典而不是列表进行排序时出错了。

def highest_n_grades(student_list, assignment_name):
  for s in student_list:
    for assignment_name in s['assignments'][1]:
      s['assignments'][1] = assignment_name
      s.sort(key=assignment_name)
    print(student_list)

highest_n_grades(student_list, assignment_name='assignment_1' )

编辑3

好吧,我也许有点进步了?

newlist2 = sorted(newlist, key=lambda k: k['assignments'][0], reverse = True)
newlist3 = sorted(newlist, key=lambda k: k['assignments'][1], reverse = True)
newlist4 = sorted(newlist, key=lambda k: k['assignments'][2], reverse = True)

这些似乎是按任务排序的。我不明白lambda在做什么,但我至少可以生成一个最高分排在第一位的列表。我觉得这是小步走。

编辑4

def highest_n_grades(student_list,  n):
  for s in student_list:
    newlist = sorted(student_list, key=lambda k: k['assignments'][0], reverse=True)
    print(newlist[:n])

highest_n_grades(student_list, 3)

输出:

[{'id': 12345, 'first_name': 'Ed', 'last_name': 'Enders', 'assignments': [('assignment_1', 4), ('assignment_2', 1), ('assignment_3', 3)]}, {'id': 12344, 'first_name': 'Didi', 'last_name': 'Dawson', 'assignments': [('assignment_1', 3), ('assignment_2', 0), ('assignment_3', 2)]}, {'id': 12343, 'first_name': 'Carl', 'last_name': 'Cape', 'assignments': [('assignment_1', 2), ('assignment_2', 4), ('assignment_3', 1)]}]
[{'id': 12345, 'first_name': 'Ed', 'last_name': 'Enders', 'assignments': [('assignment_1', 4), ('assignment_2', 1), ('assignment_3', 3)]}, {'id': 12344, 'first_name': 'Didi', 'last_name': 'Dawson', 'assignments': [('assignment_1', 3), ('assignment_2', 0), ('assignment_3', 2)]}, {'id': 12343, 'first_name': 'Carl', 'last_name': 'Cape', 'assignments': [('assignment_1', 2), ('assignment_2', 4), ('assignment_3', 1)]}]
[{'id': 12345, 'first_name': 'Ed', 'last_name': 'Enders', 'assignments': [('assignment_1', 4), ('assignment_2', 1), ('assignment_3', 3)]}, {'id': 12344, 'first_name': 'Didi', 'last_name': 'Dawson', 'assignments': [('assignment_1', 3), ('assignment_2', 0), ('assignment_3', 2)]}, {'id': 12343, 'first_name': 'Carl', 'last_name': 'Cape', 'assignments': [('assignment_1', 2), ('assignment_2', 4), ('assignment_3', 1)]}]
[{'id': 12345, 'first_name': 'Ed', 'last_name': 'Enders', 'assignments': [('assignment_1', 4), ('assignment_2', 1), ('assignment_3', 3)]}, {'id': 12344, 'first_name': 'Didi', 'last_name': 'Dawson', 'assignments': [('assignment_1', 3), ('assignment_2', 0), ('assignment_3', 2)]}, {'id': 12343, 'first_name': 'Carl', 'last_name': 'Cape', 'assignments': [('assignment_1', 2), ('assignment_2', 4), ('assignment_3', 1)]}]
[{'id': 12345, 'first_name': 'Ed', 'last_name': 'Enders', 'assignments': [('assignment_1', 4), ('assignment_2', 1), ('assignment_3', 3)]}, {'id': 12344, 'first_name': 'Didi', 'last_name': 'Dawson', 'assignments': [('assignment_1', 3), ('assignment_2', 0), ('assignment_3', 2)]}, {'id': 12343, 'first_name': 'Carl', 'last_name': 'Cape', 'assignments': [('assignment_1', 2), ('assignment_2', 4), ('assignment_3', 1)]}]
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/46317
 
951 次点击  
文章 [ 2 ]  |  最新文章 4 年前
Nick
Reply   •   1 楼
Nick    5 年前

对于初学者来说,这是一项困难的作业。困难在于lambdas、多个键排序、列表、列表切片和元组、字典,甚至是有序和无序的数据类型。我用python编程已经有10年了,但我发现它并不简单。

lambda是一个动态定义的小函数。 sorted() 将函数作为其第二个参数。它需要为每个学生调用此函数来生成排序键。sort函数比较两个学生的排序键,以确定在排序中哪个学生先进入。

从lambdas开始,最好记住:

id_key = lambda x: x[0]

相当于:

def id_key(x):
    return x[0]

此外

sorted(students, key=lambda x: x[0])

相当于:

sorted(student, key=id_key)

为了对多个值进行排序 stable sorts and their properties 是的。稳定排序算法非常适合对多个值进行排序。大多数python排序函数都是“稳定的”。

下面是使用当前结构的解决方案:

def sort_by_grade_then_id(grades):
    # sort (id, grade) tuples high grades, low ids first
    sorted_by_id = sorted(grades, key=lambda student: student[0])
    sorted_by_id_and_assignment_grade = sorted(sorted_by_id,
        key=lambda student: student[1], reverse=True)
    return sorted_by_id_and_assignment_grade


def highest_n_grades(students, assignment_name, n):
grades = []
for student in students:
    for assignment, grade in student['assignments']:
        if assignment_name == assignment:
            grades.append((student['id'], grade))
return sort_by_grade_then_id(grades)[:n]    

>>> print(highest_n_grades(student_list, 'assignment_2', 2))
[(12343, 4), (12342, 3)]

但如果你现在想要的是学生的名字而不是他的/她的身份证,你就得再做一次连续搜索才能得到。

from copy import copy

students_dict = {student['id']: student for student in copy(student_list)}
for student in students_dict.values():
    student['assignments'] = dict(student['assignments'])

列出最好的成绩会变成:

def highest_n_grades_dict(students, assignment_name, n):
    grades = [
        (id, student['assignments'][assignment_name])
        for id, student
        in students.items()
    ]
    return sort_by_grade_then_id(grades)[:n]

只有几个学生不重要,但如果你有很多学生和许多作业,这个新版本会更快。你也可以使用学生数据库来查找资料,而不必搜索和匹配。

例如:

print('Highest grades dict version...')
grades = highest_n_grades_dict(students_dict, 'assignment_2', 2)
print(grades)
print("...and dict structure easily allows us to get other student details")
names_and_grades = [
    (students_dict[id]['first_name'] + ' ' + students_dict[id]['last_name'], grade)
    for id, grade
    in grades]
print(names_and_grades)
>>> python grades.py
Highest grades dict version...
[(12343, 4), (12342, 3)]
...and dict structure easily allows us to get other student details
[('Carl Cape', 4), ('Boris Bank', 3)]

旁注:如果你经常和元组打交道,你可能会对 named tuples ,因为它们通常使元组相关的代码(包括lambda函数)更易于读、写和理解。看看我最近的回答 this question 举个例子。

vash_the_stampede
Reply   •   2 楼
vash_the_stampede    5 年前

这可以用 lambda sorted 是的。使用时 已排序 具有 兰姆达 我们先出发 key=lambda x: 是的。现在你可以想想了 x 表示列表索引,以便按 assignment_1 我们要走了 x['assignments'] 如果我们的任务是 任务1 我们知道那是 0 索引 assignments 所以在一起 key=lambda x: x['assignments'][0] 是的。现在我们也可以 sort 第二个选择,那将是我们的平局,我们将使用 x[id] 并将与我们的主要排序因子在一个元组中。我们当然应该用 reverse = True 为了得到下降的分数,但是由于我们希望我们的平局是上升的,所以我们可以在 id 使用 -(x['id'])

总的来说,这类情况如下:

lista = sorted(students, key=lambda x: (x['assignments'][0], -(x['id'])), reverse = True)

棘手的部分是为传递的赋值选择合适的赋值索引,因为您可以使用 .split('_')[1] (使用时 .split('_') 'assignment_1' 我们生成一个新列表 ['assignemnt', '1'] 在这种情况下,我们现在可以采取 [1] 索引 .split() 那就是 1 作为 int 减去1得到 0个 这是相应的索引,其余的都是从它们的索引中去掉1。

def highest_n_grades(students, assignment_name, n):
    y = int(assignment_name.split('_')[1]) - 1
    lista = sorted(students, key=lambda x: (x['assignments'][y], 'id'), reverse = True)
    return lista [:n]   

print(highest_n_grades(student_list, 'assignment_1', 3))
# [{'id': 12345, 'first_name': 'Ed', 'last_name': 'Enders', 'assignments': [('assignment_1', 4), ('assignment_2', 1), ('assignment_3', 3)]}, {'id': 12344, 'first_name': 'Didi', 'last_name': 'Dawson', 'assignments': [('assignment_1', 3), ('assignment_2', 0), ('assignment_3', 2)]}, {'id': 12343, 'first_name': 'Carl', 'last_name': 'Cape', 'assignments': [('assignment_1', 2), ('assignment_2', 4), ('assignment_3', 1)]}]

使用伪分数演示平局破发案例:

print(highest_n_grades(student_list, 'assignment_1', 3))
# [{'id': 12344, 'first_name': 'Didi', 'last_name': 'Dawson', 'assignments': [('assignment_1', 4), ('assignment_2', 0), ('assignment_3', 2)]}, {'id': 12345, 'first_name': 'Ed', 'last_name': 'Enders', 'assignments': [('assignment_1', 4), ('assignment_2', 1), ('assignment_3', 3)]}, {'id': 12342, 'first_name': 'Boris', 'last_name': 'Bank', 'assignments': [('assignment_1', 2), ('assignment_2', 3), ('assignment_3', 0)]}]

进一步阅读

.split()

https://docs.python.org/3/library/stdtypes.html

关于使用 已排序

https://docs.python.org/3/library/functions.html https://wiki.python.org/moin/HowTo/Sorting