Как избежать побочных эффектов при понимании списка - PullRequest
0 голосов
/ 29 мая 2020

Какой Pythoni c самый эффективный и эффективный способ обработки списка словарей и избежания побочных эффектов (каковы побочные эффекты)?

Точнее: почему следующий код создает объект-генератор, в то время как любой другой аналогичный код дает желаемый результат?

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)

Я просмотрел Документ о структурах данных , включая понимание списка, и нашел лучший способ добиться того же результата:

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 ]

1 голос
/ 29 мая 2020

Ваш конкретный c вопрос печатает только представление вашего фактического объекта-генератора, сформированного выражением генератора, а именно этого -

(sum(dictionary[site] for site in dictionary) for dictionary in listofdictionaries)

См. Этот ответ о печати генераторов для получения дополнительной информации - { ссылка }

Для этого примера вам может быть лучше использовать понимание списка, например

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) , но, согласно предыдущему ответу, вы не изменяете свой словарь в в любом случае с этими методами, чтобы не было побочных эффектов.

1 голос
/ 29 мая 2020

Вы можете подойти довольно близко, добавив функцию для вычисления суммы одного словаря и используя понимание списка следующим образом:

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]

Но ваш двухстрочный текст не должен иметь никаких сторон последствия. Я не знаю, какие сообщения вы имеете в виду, но если вы не изменяете списки, тогда все будет в порядке, и они не должны быть изменены в конце.

...