Вы, сэр, неправильно поняли списочные представления.
Что вы, вероятно, хотели (на словах)
Я хочу удалить все недействительные идентификаторы проекта.
Что вы написали
project_keys = [project_keys.remove(project.proj_id)
for project in projects.itervalues() if project.invalid]
Что на самом деле происходит
dummy = []
for project in projects.itervalues():
if project.invalid:
dummy.append(project_keys.remove(project.proj_id)) #what are you
project_keys = dummy #removing items from?
del dummy
Что на самом деле происходит (теперь с более «функциональным»)
mapped-fun = lambda project: project_keys.remove(project.proj_id)
filtering-fun = lambda project: project.invalid
project_keys = map(mapped-fun, filter(filtering-fun, projects.itervalues()))
Как видите, списочные выражения - это , а не синтаксический сахар вокруг for
циклов. Скорее, списочные выражения являются синтаксическим сахаром вокруг map()
и filter()
: применить функцию ко всем элементам в последовательности , которые сопоставьте условие и получите в ответ список результатов.
Здесь под функцией фактически подразумевается преобразование ввода в вывод без побочных эффектов. Это означает, что вы «не можете» использовать методы, которые изменяют сам ввод, например list.sort()
; вам придется использовать их функциональные эквиваленты, такие как sorted()
.
Однако под словом «не могу» я не имею в виду, что вы будете получать сообщения об ошибках или носовые демоны ; Я имею в виду, что вы злоупотребляете языком. В вашем случае, оценка понимания списка, которое происходит, когда вы присваиваете его переменной, действительно дает ожидаемые побочные эффекты - но вызывает ли это их на предполагаемых переменных?
Видите ли, единственная причина, по которой это может выполняться без ошибок, состоит в том, что до этого понимания списка был другой список, называемый project_keys
, и этот список, который вы фактически меняете !
Понимание списков является результатом функционального программирования, которое отвергает побочные эффекты. Помните об этом при использовании списочных представлений.
Итак, вот мыслительный процесс, который вы можете использовать, чтобы действительно получить понимание списка, которое вы хотели.
Что вы на самом деле хотели (словами)
Я хочу, чтобы все идентификаторы проекта были действительными (= недействительными).
Что вы на самом деле хотели
dummy = []
for project in projects.itervalues():
if not project.invalid:
dummy.append(project.proj_id)
project_keys = dummy
del dummy
То, что вы на самом деле хотели (теперь с более функциональным)
mapped-fun = lambda project: project.proj_id
filtering-fun = lambda project: not project.invalid
project_keys = map(mapped-fun, filter(filtering-fun, projects.itervalues()))
Что вы на самом деле хотели (теперь для понимания списка)
project_keys = [project.proj_id for project in projects.itervalues()
if not project.invalid]