Python字典列表 - 添加具有相同键名的字典

5

我有一个像这样的Python列表:

user = [
        {'name': 'ozzy', 'quantity': 5},
        {'name': 'frank', 'quantity': 4},
        {'name': 'ozzy', 'quantity': 3},
        {'name': 'frank', 'quantity': 2},
        {'name': 'james', 'quantity': 7},
        ]

我正在尝试编写代码,将具有相同名称的字典连接在一起,并同时添加数量。最终列表如下:
user = [
        {'name': 'ozzy', 'quantity': 8},
        {'name': 'frank', 'quantity': 6},
        {'name': 'james', 'quantity': 7}
        ]

我尝试了一些方法,但是我很难得到正确的代码。下面的代码有点在添加值(实际上我的列表要长得多,我只是添加了一小部分作为参考)。

newList = []
    quan = 0
    for i in range(0,len(user)):      
        originator = user[i]['name']
        for j in range(i+1,len(user)):
            if originator == user[j]['name']:
                quan = user[i]['quantity'] + user[j]['quantity']
                newList.append({'name': originator, 'Quantity': quan})

请问您能否帮我获取正确的代码?


1
你写的代码有什么问题吗?输出结果不正确吗?请提供您当前的输出和期望的输出。 - Zinki
输出的相对顺序是否应该保持不变? - jdehesa
@Zinki 他们给出了预期的输出。 - Chris_Rands
5个回答

5

只需计算 collections.Counter 中的项目,如有需要可以展开成字典列表:

user = [
        {'name': 'ozzy', 'quantity': 5},
        {'name': 'frank', 'quantity': 4},
        {'name': 'ozzy', 'quantity': 3},
        {'name': 'frank', 'quantity': 2},
        {'name': 'james', 'quantity': 7},
        ]

import collections

d = collections.Counter()
for u in user:
    d[u['name']] += u['quantity']

print(dict(d))

newlist = [{'name' : k, 'quantity' : v} for k,v in d.items()]

print(newlist)

首先输出Counter 字典,已经足够:

{'frank': 6, 'ozzy': 8, 'james': 7}

并使用字典列表重新格式化输出的结果:

[{'name': 'frank', 'quantity': 6}, {'name': 'ozzy', 'quantity': 8}, {'name': 'james', 'quantity': 7}]

1

使用标准字典也可以很轻松地解决问题。这里不需要使用CounterOrderedDict

user = [
        {'name': 'ozzy', 'quantity': 5},
        {'name': 'frank', 'quantity': 4},
        {'name': 'ozzy', 'quantity': 3},
        {'name': 'frank', 'quantity': 2},
        {'name': 'james', 'quantity': 7},
        ]

dic = {}
for item in user:
  n, q = item.values()
  dic[n] = dic.get(n,0) + q
print(dic)

user = [{'name':n, 'quantity':q} for n,q in dic.items()]
print(user)

结果:

{'ozzy': 8, 'frank': 6, 'james': 7}
[{'name': 'ozzy', 'quantity': 8}, {'name': 'frank', 'quantity': 6}, {'name': 'james', 'quantity': 7}]

谢谢,这个很好用,但是当我有一个带空格的键比如 'name surname' 时,我不能在 dict() 中使用它,而是用 {'name surname' : k, 'quantity' : v} 解决了这个问题。 - Rikkas
好的观点!由于您的示例没有显示那种情况,我跳过了它。我已经编辑了答案... - sciroccorics

0
我建议改变输出字典的样式,使其实际可用。考虑使用类似以下的格式。
user = [
        {'name': 'ozzy', 'quantity': 5},
        {'name': 'frank', 'quantity': 4},
        {'name': 'ozzy', 'quantity': 3},
        {'name': 'frank', 'quantity': 2},
        {'name': 'james', 'quantity': 7},
        ]

data = {}
for i in user:
    print(i)
    if i['name'] in data:
        data[i['name']] += i['quantity']
    else:
        data.update({i['name']: i['quantity']})

print(data)

{'frank': 6, 'james': 7, 'ozzy': 8}

你的for循环中的所有内容都可以使用.get()压缩为一行代码 - data[i['name']] = data.get(i['name'], 0) + i['quantity'],但这仍然无法得到OP想要的输出。 - asongtoruin

0
如果您需要保持原始的相对顺序:
from collections import OrderedDict

user = [
        {'name': 'ozzy', 'quantity': 5},
        {'name': 'frank', 'quantity': 4},
        {'name': 'ozzy', 'quantity': 3},
        {'name': 'frank', 'quantity': 2},
        {'name': 'james', 'quantity': 7},
        ]

d = OrderedDict()
for item in user:
    d[item['name']] = d.get(item['name'], 0) + item['quantity']

newlist = [{'name' : k, 'quantity' : v} for k, v in d.items()]
print(newlist)

输出:

[{'name': 'ozzy', 'quantity': 8}, {'name': 'frank', 'quantity': 6}, {'name': 'james', 'quantity': 7}]

0
user = [
    {'name': 'ozzy', 'quantity': 8},
    {'name': 'frank', 'quantity': 6},
    {'name': 'james', 'quantity': 7}
]

reference_dict = {}

for item in user :
    reference_dict[item['name']] = reference_dict.get(item['name'],0) + item['quantity']

#Creating new list from reference dict
updated_user = [{'name' : k , 'quantity' : v} for k,v in reference_dict.items()]

print updated_user

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接