避免列表理解中的副作用

问题描述 投票:0回答:2

处理字典列表并避免副作用(什么是副作用)的最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
python python-3.x list-comprehension nested-loops
2个回答
0
投票

您可以通过添加一个函数来计算一个字典的总和,并像这样使用列表理解来达到相当接近的效果:

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]

但是,您的两线客车不应有任何副作用。我不知道您指的是什么帖子,但是如果您不修改列表,则应该可以,并且最后应该保持不变。


0
投票

您的特定问题仅打印由生成器表达式形成的实际生成器对象的表示,即此一-

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

© www.soinside.com 2019 - 2024. All rights reserved.