原始列表project_keys = sorted(projects.keys())
为[101, 102, 103, 104, 105, 106, 107, 108, 109, 110]
,其中以下项目今年被视为invalid
:108,109,110。
因此:
for project in projects.itervalues():
# The projects dictionary is mapped to the Project class
if project.invalid:
# Where invalid is a Bool parameter in the Project class
project_keys.remove(project.proj_id)
print project_keys
这将返回一个整数列表(项目ID为):
[101, 102, 103, 104, 105, 106, 107]
甜。
现在,我希望它使用列表推导尝试相同的事情。
project_keys = [project_keys.remove(project.proj_id) for project in projects.itervalues() if project.invalid
print project_keys
返回:
[None, None, None]
所以我填充的列表与删除的元素的编号相同,但它们是None
的?
有人可以指出我做错了吗?
另外,为什么我会在顶部的for-if
块上使用列表推导?简明?看起来更好吗?
答案 0 :(得分:6)
您的列表理解使用副作用。只是执行它应该更新project_keys以给出你想要的结果。
[project_keys.remove(project.proj_id)
for project in projects.itervalues()
if project.invalid]
remove
的返回值为None
。将列表理解的结果分配给project_keys
是您出错的地方。
尽管如此,一个简单的循环可能更清晰。使用副作用的列表理解可能会令人困惑。
但是,您可以稍微不同的方式解决问题:
project_keys = sorted(project.proj_id
for project in projects.itervalues()
if not project.invalid)
这可以保留您感兴趣的项目,而不是删除那些您不感兴趣的项目。我上面给出的示例使用生成器表达式而不是列表推导,但它可以使用。
答案 1 :(得分:4)
先生,您误解了列表理解。
我想删除所有无效的项目ID。
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()
。
但是,“不能”,我并不是说你会得到错误信息或nasal demons;我的意思是你在滥用这种语言。在你的情况下,当你将它分配给变量时对列表理解的评估确实会产生预期的副作用 - 但它是否会在预期的变量上产生它们?
请参阅,唯一可以在没有错误的情况下执行的原因是,在此列表理解之前,有另一个名为project_keys
的列表,而 列表你实际上在改变!
列表理解是函数式编程的结果,它拒绝副作用。使用列表推导时请记住这一点。
所以这是一个思考过程,你可以用来实际获得你想要的列表理解。
我想要所有有效的项目ID(=无效。)
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]