Python 使用相同的键从dict.values()获取最大值

Python 使用相同的键从dict.values()获取最大值,python,dictionary,iteration,Python,Dictionary,Iteration,我有这个csv.com文件。假设我已经使用了DictReader,现在我有了一些充满dicts的列表,比如('name':'Andrew'),('points':18)等等 name points Andrew 18 Kate 10 Jack 55 Andrew 31 Andrew 100 Jack 58 Andrew 34 Kate 22 Jack 5 Andrew 72 我要做的是返回一个键值对,如Andrew:(5100),其中值为: 我在一

我有这个csv.com文件。假设我已经使用了
DictReader
,现在我有了一些充满dicts的列表,比如
('name':'Andrew'),('points':18)
等等

name    points
Andrew  18
Kate    10
Jack    55
Andrew  31
Andrew  100
Jack    58
Andrew  34
Kate    22
Jack    5
Andrew  72
我要做的是返回一个键值对,如
Andrew:(5100)
,其中值为:

  • 我在一张名单上见过这个名字多少次
  • 点表中此名称的最大编号
  • 我对第一项任务没有问题,但找不到解决方案 第二个。这就是我试图做的:

    name_counter = defaultdict(int)
    max_points = defaultdict(int)
    for dictionary in list_from_csv:
        name_counter[dictionary['name']] += 1 #every time I meet the name, I add +1 to the value
        max_points[dictionary['name']] = ??? 
    
    我想用max(dictionary[points]),但是max应该从数字的数量中选择,而不仅仅是一个。可能会创建一个列表,但不确定如何创建。还有其他想法吗

    非常感谢您的帮助


    另外,在我有了这两个dict之后,我需要根据键合并它们,但我希望不会那么难。

    您可以使用
    itertools。groupby

    import itertools
    data = [{'name': 'Andrew', 'points': 18}, {'name': 'Kate', 'points': 10}, {'name': 'Jack', 'points': 55}, {'name': 'Andrew', 'points': 31}, {'name': 'Andrew', 'points': 100}, {'name': 'Jack', 'points': 58}, {'name': 'Andrew', 'points': 34}, {'name': 'Kate', 'points': 22}, {'name': 'Jack', 'points': 5}, {'name': 'Andrew', 'points': 72}]
    grouped_data = [[a, list(b)] for a, b in itertools.groupby(sorted(data, key=lambda x:x['name']), key=lambda x:x['name'])]
    final_data = [{a:(len(b), max(b, key=lambda x:x['points'])['points'])} for a, b in grouped_data]
    
    输出:

    [{'Andrew': (5, 100)}, {'Jack': (3, 58)}, {'Kate': (2, 22)}]
    

    您可以使用
    itertools.groupby

    import itertools
    data = [{'name': 'Andrew', 'points': 18}, {'name': 'Kate', 'points': 10}, {'name': 'Jack', 'points': 55}, {'name': 'Andrew', 'points': 31}, {'name': 'Andrew', 'points': 100}, {'name': 'Jack', 'points': 58}, {'name': 'Andrew', 'points': 34}, {'name': 'Kate', 'points': 22}, {'name': 'Jack', 'points': 5}, {'name': 'Andrew', 'points': 72}]
    grouped_data = [[a, list(b)] for a, b in itertools.groupby(sorted(data, key=lambda x:x['name']), key=lambda x:x['name'])]
    final_data = [{a:(len(b), max(b, key=lambda x:x['points'])['points'])} for a, b in grouped_data]
    
    输出:

    [{'Andrew': (5, 100)}, {'Jack': (3, 58)}, {'Kate': (2, 22)}]
    

    每次获得新值时,您只需确定如何处理
    max_points[name]
    ,对吗

    让我们假设,在每次迭代中,
    max_points[name]
    已经被正确设置为迄今为止看到的最高值。那么,您需要如何处理新值

    简单:如果
    大于迄今为止看到的最高值,则为新的最高值;如果不是,旧的最高值就是新的最高值

    这正是
    max
    所做的。因此:

    max_points[dictionary['name']] = max(max_points[dictionary['name']], points)
    
    现在我们只需要验证这个假设是正确的

    • 因为您使用的是
      defaultdict(int)
      ,所以它总是从0开始。如果你的分数是负数,那就错了,但除此之外,这是正确的,你迄今为止看到的最高分数,对任何人来说,都是0

    • 在每一步中,如果上一步是正确的,那么下一步之后也是正确的,因为
      max
      就是这样做的

    • 所以,通过归纳,它在最后是正确的


    作为旁注,与其一遍遍地重复
    dictionary['name']
    ,不如像这样:

    for dictionary in list_from_csv:
        name = dictionary['name']
        name_counter[name] += 1
        max_points[name] = max(max_points[name], points)
    

    每次获得新值时,您只需确定如何处理
    max_points[name]
    ,对吗

    让我们假设,在每次迭代中,
    max_points[name]
    已经被正确设置为迄今为止看到的最高值。那么,您需要如何处理新值

    简单:如果
    大于迄今为止看到的最高值,则为新的最高值;如果不是,旧的最高值就是新的最高值

    这正是
    max
    所做的。因此:

    max_points[dictionary['name']] = max(max_points[dictionary['name']], points)
    
    现在我们只需要验证这个假设是正确的

    • 因为您使用的是
      defaultdict(int)
      ,所以它总是从0开始。如果你的分数是负数,那就错了,但除此之外,这是正确的,你迄今为止看到的最高分数,对任何人来说,都是0

    • 在每一步中,如果上一步是正确的,那么下一步之后也是正确的,因为
      max
      就是这样做的

    • 所以,通过归纳,它在最后是正确的


    作为旁注,与其一遍遍地重复
    dictionary['name']
    ,不如像这样:

    for dictionary in list_from_csv:
        name = dictionary['name']
        name_counter[name] += 1
        max_points[name] = max(max_points[name], points)
    

    为完整起见,以下是第三方熊猫一号班轮:

    res = df.groupby('name')['points'].agg(['size', 'max'])
    
    结果

    print(res)
    
            size  max
    name             
    Andrew     5  100
    Jack       3   58
    Kate       2   22
    
    设置

    import pandas as pd
    from io import StringIO
    
    mystr = StringIO("""name    points
    Andrew  18
    Kate    10
    Jack    55
    Andrew  31
    Andrew  100
    Jack    58
    Andrew  34
    Kate    22
    Jack    5
    Andrew  72""")
    
    df = pd.read_csv(mystr, delim_whitespace=True)
    

    为完整起见,以下是第三方熊猫一号班轮:

    res = df.groupby('name')['points'].agg(['size', 'max'])
    
    结果

    print(res)
    
            size  max
    name             
    Andrew     5  100
    Jack       3   58
    Kate       2   22
    
    设置

    import pandas as pd
    from io import StringIO
    
    mystr = StringIO("""name    points
    Andrew  18
    Kate    10
    Jack    55
    Andrew  31
    Andrew  100
    Jack    58
    Andrew  34
    Kate    22
    Jack    5
    Andrew  72""")
    
    df = pd.read_csv(mystr, delim_whitespace=True)
    

    这是一个不使用csv以外的任何额外导入的解决方案

    我已将您的示例数据用作csv文件。我已经阅读了内容并创建了一个元组列表(名称、点)

    元组列表如下所示

    [('Andrew', '18'), ('Kate', '10'), ('Jack', '55'), ('Andrew', '31'), ('Andrew', '100'), ('Jack', '58'), ('Andrew', '34'), ('Kate', '22'), ('Jack', '5'), ('Andrew', '72')]
    
    结果_dict以{key:(tuple_0,tuple_1),}格式存储数据 像

    字典中的值由其
    标识,在本例中,该键是
    名称

    dictionary['key']
    所以这里
    result\u dict[name]
    元组中的数据可以作为普通列表访问,如元组[0]和元组[1]
    所以这里是
    result\u dict[name][0]
    result\u dict[name][1]

    result_dict = {}
    for dict_item in list_of_tuples:
        name = dict_item[0]
        points = int(dict_item[1])
        if name in result_dict:
            name_count = result_dict[name][0]
            max_points = result_dict[name][1]
            result_dict[name] = (name_count + 1, points if max_points < points else max_points)
        else:
            # the name isn't in the dictionary, so we add the "name: (name_count, max_points)" to it
            result_dict[name] = (1, points)
    

    这是一个不使用csv以外的任何额外导入的解决方案

    我已将您的示例数据用作csv文件。我已经阅读了内容并创建了一个元组列表(名称、点)

    元组列表如下所示

    [('Andrew', '18'), ('Kate', '10'), ('Jack', '55'), ('Andrew', '31'), ('Andrew', '100'), ('Jack', '58'), ('Andrew', '34'), ('Kate', '22'), ('Jack', '5'), ('Andrew', '72')]
    
    结果_dict以{key:(tuple_0,tuple_1),}格式存储数据 像

    字典中的值由其
    标识,在本例中,该键是
    名称

    dictionary['key']
    所以这里
    result\u dict[name]
    元组中的数据可以作为普通列表访问,如元组[0]和元组[1]
    所以这里是
    result\u dict[name][0]
    result\u dict[name][1]

    result_dict = {}
    for dict_item in list_of_tuples:
        name = dict_item[0]
        points = int(dict_item[1])
        if name in result_dict:
            name_count = result_dict[name][0]
            max_points = result_dict[name][1]
            result_dict[name] = (name_count + 1, points if max_points < points else max_points)
        else:
            # the name isn't in the dictionary, so we add the "name: (name_count, max_points)" to it
            result_dict[name] = (1, points)
    

    合并后的dict应该是什么样子?谷歌如何使用
    groupby
    功能。我想你可以从这里结束了,你展示的不是一个充满dict的列表,它甚至不是任何东西的合法Python语法。如果您想让我们向您展示如何转换输入,请给我们一个可用的输入示例。合并的dict应该是什么样子?谷歌如何使用
    groupby
    功能。我想你可以从这里结束了,你展示的不是一个充满dict的列表,它甚至不是任何东西的合法Python语法。如果您希望我们向您展示如何转换输入,请给我们一个可用的输入示例。我的,谢谢!)这是一个非常好的答案!我的天啊,谢谢你!:)这是一个非常好的答案!谢谢,这真的很有帮助!谢谢,这真的很有帮助!谢谢你这么详细的回答!谢谢你这么详细的回答!