有没有办法根据字典键映射一个字典列表?
Is there a way to map a list of dicts according to the dict keys?
我有一个字典列表,看起来像
[{'n': 3, 'topic': 4, 'shared_via_twitter': 'N'}, {'n': 72, 'topic': 1, 'shared_via_twitter': 'Y'}, {'n': 46, 'topic': 2, 'shared_via_twitter': 'N'}, {'n': 36, 'topic': 2, 'shared_via_twitter': 'Y'}, {'n': 5, 'topic': 4, 'shared_via_twitter': 'N'}, {'n': 29, 'topic': 2, 'shared_via_twitter': 'Y'}, {'n': 102, 'topic': 2, 'shared_via_twitter': 'Y'}, {'n': 13, 'topic': 8, 'shared_via_twitter': 'Y'}, {'n': 52, 'topic': 2, 'shared_via_twitter': 'N'}, {'n': 24, 'topic': 5, 'shared_via_twitter': 'N'}]
我希望能够将具有相同 topic
和 shared_via_twitter
值的所有字典合并为一个并更新新字典的 n
值以反映总和。
例如
如果我有
[{'n': 3, 'topic': 1, 'shared_via_twitter': 'N'}, {'n': 7, 'topic': 1, 'shared_via_twitter': 'N'}]
那我要{'n': 10, 'topic': 1, 'shared_via_twitter': 'N'}
作为结果。
我正在考虑使用类似
的地图
def xs(x):
# {'n': 3, 'topic': 4, 'shared_via_twitter': 'N'}
# {'n': 7, 'topic': 4, 'shared_via_twitter': 'N'}
if x['topic'] == v['topic'] and x['shared_via_twitter'] == v['shared_via_twitter']:
x['n']+=v['n']
v = dict(x)
return x
g = map(xs, rows)
但这显然不像 clean/work。
任何想法将不胜感激。
这不是映射操作。目前尚不清楚您尝试做什么,确切地说,因为 v
未定义。但基本上,map
不是最好的工具,因为它将一个函数应用于每个元素,你想按你的键分组并汇总 "n"
的值并求和。使用字典分组成语:
>>> data = [{'n': 3, 'topic': 4, 'shared_via_twitter': 'N'}, {'n': 72, 'topic': 1, 'shared_via_twitter': 'Y'}, {'n': 46, 'topic': 2, 'shared_via_twitter': 'N'}, {'n': 36, 'topic': 2, 'shared_via_twitter': 'Y'}, {'n': 5, 'topic': 4, 'shared_via_twitter': 'N'}, {'n': 29, 'topic': 2, 'shared_via_twitter': 'Y'}, {'n': 102, 'topic': 2, 'shared_via_twitter': 'Y'}, {'n': 13, 'topic': 8, 'shared_via_twitter': 'Y'}, {'n': 52, 'topic': 2, 'shared_via_twitter': 'N'}, {'n': 24, 'topic': 5, 'shared_via_twitter': 'N'}]
>>> grouper = {}
>>> for d in data:
... key = d['topic'], d['shared_via_twitter']
... grouper[key] = grouper.get(key, 0) + d['n']
...
>>> grouper
{(4, 'N'): 8, (1, 'Y'): 72, (2, 'N'): 98, (2, 'Y'): 167, (8, 'Y'): 13, (5, 'N'): 24}
您可以将其转换为您的最终形式:
>>> [dict(topic=t, shared_via_twitter=s, n=n) for (t, s), n in grouper.items()]
[{'topic': 4, 'shared_via_twitter': 'N', 'n': 8}, {'topic': 1, 'shared_via_twitter': 'Y', 'n': 72}, {'topic': 2, 'shared_via_twitter': 'N', 'n': 98}, {'topic': 2, 'shared_via_twitter': 'Y', 'n': 167}, {'topic': 8, 'shared_via_twitter': 'Y', 'n': 13}, {'topic': 5, 'shared_via_twitter': 'N', 'n': 24}]
如果我理解正确,请尝试 collections.defaultdict
或 collections.Counter
:
import collections
totals = collections.Counter()
for d in data:
totals[d['topic'], d['shared_via_twitter']] += d['n']
这会将其保留在类似于 {(1, 'N'): 10}
的结构中,您可以按原样使用它,也可以将其转换为字典列表形式:
converted = [
{'n': n, 'topic': topic, 'shared_via_twitter': shared_via_twitter}
for (topic, shared_via_twitter), n in totals.items()
]
我有一个字典列表,看起来像
[{'n': 3, 'topic': 4, 'shared_via_twitter': 'N'}, {'n': 72, 'topic': 1, 'shared_via_twitter': 'Y'}, {'n': 46, 'topic': 2, 'shared_via_twitter': 'N'}, {'n': 36, 'topic': 2, 'shared_via_twitter': 'Y'}, {'n': 5, 'topic': 4, 'shared_via_twitter': 'N'}, {'n': 29, 'topic': 2, 'shared_via_twitter': 'Y'}, {'n': 102, 'topic': 2, 'shared_via_twitter': 'Y'}, {'n': 13, 'topic': 8, 'shared_via_twitter': 'Y'}, {'n': 52, 'topic': 2, 'shared_via_twitter': 'N'}, {'n': 24, 'topic': 5, 'shared_via_twitter': 'N'}]
我希望能够将具有相同 topic
和 shared_via_twitter
值的所有字典合并为一个并更新新字典的 n
值以反映总和。
例如 如果我有
[{'n': 3, 'topic': 1, 'shared_via_twitter': 'N'}, {'n': 7, 'topic': 1, 'shared_via_twitter': 'N'}]
那我要{'n': 10, 'topic': 1, 'shared_via_twitter': 'N'}
作为结果。
我正在考虑使用类似
的地图def xs(x):
# {'n': 3, 'topic': 4, 'shared_via_twitter': 'N'}
# {'n': 7, 'topic': 4, 'shared_via_twitter': 'N'}
if x['topic'] == v['topic'] and x['shared_via_twitter'] == v['shared_via_twitter']:
x['n']+=v['n']
v = dict(x)
return x
g = map(xs, rows)
但这显然不像 clean/work。 任何想法将不胜感激。
这不是映射操作。目前尚不清楚您尝试做什么,确切地说,因为 v
未定义。但基本上,map
不是最好的工具,因为它将一个函数应用于每个元素,你想按你的键分组并汇总 "n"
的值并求和。使用字典分组成语:
>>> data = [{'n': 3, 'topic': 4, 'shared_via_twitter': 'N'}, {'n': 72, 'topic': 1, 'shared_via_twitter': 'Y'}, {'n': 46, 'topic': 2, 'shared_via_twitter': 'N'}, {'n': 36, 'topic': 2, 'shared_via_twitter': 'Y'}, {'n': 5, 'topic': 4, 'shared_via_twitter': 'N'}, {'n': 29, 'topic': 2, 'shared_via_twitter': 'Y'}, {'n': 102, 'topic': 2, 'shared_via_twitter': 'Y'}, {'n': 13, 'topic': 8, 'shared_via_twitter': 'Y'}, {'n': 52, 'topic': 2, 'shared_via_twitter': 'N'}, {'n': 24, 'topic': 5, 'shared_via_twitter': 'N'}]
>>> grouper = {}
>>> for d in data:
... key = d['topic'], d['shared_via_twitter']
... grouper[key] = grouper.get(key, 0) + d['n']
...
>>> grouper
{(4, 'N'): 8, (1, 'Y'): 72, (2, 'N'): 98, (2, 'Y'): 167, (8, 'Y'): 13, (5, 'N'): 24}
您可以将其转换为您的最终形式:
>>> [dict(topic=t, shared_via_twitter=s, n=n) for (t, s), n in grouper.items()]
[{'topic': 4, 'shared_via_twitter': 'N', 'n': 8}, {'topic': 1, 'shared_via_twitter': 'Y', 'n': 72}, {'topic': 2, 'shared_via_twitter': 'N', 'n': 98}, {'topic': 2, 'shared_via_twitter': 'Y', 'n': 167}, {'topic': 8, 'shared_via_twitter': 'Y', 'n': 13}, {'topic': 5, 'shared_via_twitter': 'N', 'n': 24}]
如果我理解正确,请尝试 collections.defaultdict
或 collections.Counter
:
import collections
totals = collections.Counter()
for d in data:
totals[d['topic'], d['shared_via_twitter']] += d['n']
这会将其保留在类似于 {(1, 'N'): 10}
的结构中,您可以按原样使用它,也可以将其转换为字典列表形式:
converted = [
{'n': n, 'topic': topic, 'shared_via_twitter': shared_via_twitter}
for (topic, shared_via_twitter), n in totals.items()
]