处理字典列表并避免副作用(什么是副作用)的最Python高效的方法是什么?
更具体地说:为什么以下代码会生成一个生成器对象,而几乎其他任何类似的代码也会生成所需的输出?
print(sum(dictionary[site] for site in dictionary) for dictionary in listofdictionaries)
某些背景
我从摆弄**kwargs
开始,制作了我认为非常糟糕的代码。
def testing(**kwargs):
mysum = 0
for kw in kwargs:
mysum += kwargs[kw]
print(mysum)
listofdictionaries = [{"site1": 1, "room1": 2, "day1": 3}, {"site2": 4, "room2": 5, "day2": 6}]
for dictionary in listofdictionaries:
testing(**dictionary)
我查看了包括列表理解在内的Data Structures Document,并找到了实现相同输出的更好方法:
listofdictionaries = [{"site1": 1, "room1": 2, "day1": 3}, {"site2": 4, "room2": 5, "day2": 6}]
for dictionary in listofdictionaries:
mysum = 0
for value in dictionary:
mysum += dictionary[value]
print(mysum)
然后变得更聪明,并将其缩短一些:
for dictionary in listofdictionaries:
print(sum(dictionary[value] for value in dictionary))
我真的没有兴趣将其设置为单线,但是在阅读了Stack Overflow上无数的关于理解“副作用”的列表理解文章之后,我觉得可能存在采取此步骤的额外步骤。也许我不明白是什么副作用。
无论如何,这些都应产生输出:
6
15
答案 0 :(得分:1)
您可以通过添加一个函数来计算一个字典的总和,并像这样使用列表理解来达到非常接近的目的:
def dict_sum(dictionary):
mysum = 0
for value in dictionary:
mysum += dictionary[value]
return mysum
print([dict_sum(dictionary) for dictionary in listofdictionaries])
>> [6, 15]
但是,您的两线客车不应有任何副作用。我不知道您指的是什么帖子,但是如果您不修改列表,则应该没事,最后应该保持不变。
答案 1 :(得分:1)
您的特定问题仅打印由生成器表达式形成的实际生成器对象的表示,即该表达式-
(sum(dictionary[site] for site in dictionary) for dictionary in listofdictionaries)
有关详细信息,请参见打印生成器上的此答案- https://stackoverflow.com/a/44616115
对于此示例,您最好使用列表理解功能,例如
print([sum(dictionary.values()) for dictionary in listofdictionaries])
您可以通过先取消生成生成器来打印生成器,但是在此示例中,它看起来可读性和有效性都较低-
print(*(sum(dictionary.values()) for dictionary in listofdictionaries))
副作用可能是一个相当宽泛的术语-https://en.wikipedia.org/wiki/Side_effect_(computer_science),但是根据前面的答案,您不会使用这些方法以任何方式修改字典,因此没有副作用。