避免列表理解中的副作用

时间:2020-05-28 23:28:10

标签: python python-3.x list-comprehension nested-loops

处理字典列表并避免副作用(什么是副作用)的最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

2 个答案:

答案 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),但是根据前面的答案,您不会使用这些方法以任何方式修改字典,因此没有副作用。