python Counter 是否预期表现如下?
Is python Counter expected to behave as follows?
我有一个字典列表如下
[
{'sex': 2, 'newspaper_sheet__country': 'ML', 'n': 7},
{'sex': 1, 'newspaper_sheet__country': 'ML', 'n': 5},
{'sex': 2, 'newspaper_sheet__country': 'ML', 'n': 10}
]
然后我有 2 个计数器
from collections import Counter
counts = Counter()
counts1 = Counter()
我正在按以下格式更新两个计数器
for row in rows:
counts.update({(row['sex'], row['newspaper_sheet__country']): row['n']})
和
counts1.update({(row['sex'], row['newspaper_sheet__country']): row['n'] for row in rows})
我希望 2 个计数的值相同,因为唯一的区别是 1 个使用 for 循环,另一个使用字典理解。
为什么这两个值不同?
通过在 for
循环的每次迭代中调用 Counter.update
,Counter
对象将根据每次调用的输入字典进行更新。
通过字典理解,键值在传递给 Counter.update
之前首先聚合到字典中。由于字典理解中复制键的后面的值会覆盖相同键的前面的值,因此键 (2, 'ML')
的值 10
会覆盖相同键的值 7
,从而导致Counter
对象最终没有考虑值 7
。
因为在这样的循环中调用 .update
并不等同于传递该字典理解的结果,请查看该字典理解创建的内容:
>>> rows = [
... {'sex': 2, 'newspaper_sheet__country': 'ML', 'n': 7},
... {'sex': 1, 'newspaper_sheet__country': 'ML', 'n': 5},
... {'sex': 2, 'newspaper_sheet__country': 'ML', 'n': 10}
... ]
>>> {(row['sex'], row['newspaper_sheet__country']): row['n'] for row in rows}
{(2, 'ML'): 10, (1, 'ML'): 5}
字典有唯一的键,最后看到的条目被保留。
不同之处在于 update()
是通过列表推导完成的。
使用基于 for 循环的方法,计数器每次都会更新并聚合匹配键的计数,但是使用列表理解方法,它只会得到一个具有唯一键的字典。
列表理解方法可以分解为:
dic = {(row['sex'], row['newspaper_sheet__country']): row['n'] for row in rows}
print(dic) # dic only contains unique key value pairs here
counts1.update(dic)
因此,counts1
仅更新一次,而 counts
由于基于循环的方法而更新多次。
我有一个字典列表如下
[
{'sex': 2, 'newspaper_sheet__country': 'ML', 'n': 7},
{'sex': 1, 'newspaper_sheet__country': 'ML', 'n': 5},
{'sex': 2, 'newspaper_sheet__country': 'ML', 'n': 10}
]
然后我有 2 个计数器
from collections import Counter
counts = Counter()
counts1 = Counter()
我正在按以下格式更新两个计数器
for row in rows:
counts.update({(row['sex'], row['newspaper_sheet__country']): row['n']})
和
counts1.update({(row['sex'], row['newspaper_sheet__country']): row['n'] for row in rows})
我希望 2 个计数的值相同,因为唯一的区别是 1 个使用 for 循环,另一个使用字典理解。
为什么这两个值不同?
通过在 for
循环的每次迭代中调用 Counter.update
,Counter
对象将根据每次调用的输入字典进行更新。
通过字典理解,键值在传递给 Counter.update
之前首先聚合到字典中。由于字典理解中复制键的后面的值会覆盖相同键的前面的值,因此键 (2, 'ML')
的值 10
会覆盖相同键的值 7
,从而导致Counter
对象最终没有考虑值 7
。
因为在这样的循环中调用 .update
并不等同于传递该字典理解的结果,请查看该字典理解创建的内容:
>>> rows = [
... {'sex': 2, 'newspaper_sheet__country': 'ML', 'n': 7},
... {'sex': 1, 'newspaper_sheet__country': 'ML', 'n': 5},
... {'sex': 2, 'newspaper_sheet__country': 'ML', 'n': 10}
... ]
>>> {(row['sex'], row['newspaper_sheet__country']): row['n'] for row in rows}
{(2, 'ML'): 10, (1, 'ML'): 5}
字典有唯一的键,最后看到的条目被保留。
不同之处在于 update()
是通过列表推导完成的。
使用基于 for 循环的方法,计数器每次都会更新并聚合匹配键的计数,但是使用列表理解方法,它只会得到一个具有唯一键的字典。
列表理解方法可以分解为:
dic = {(row['sex'], row['newspaper_sheet__country']): row['n'] for row in rows}
print(dic) # dic only contains unique key value pairs here
counts1.update(dic)
因此,counts1
仅更新一次,而 counts
由于基于循环的方法而更新多次。