为什么这个列表理解没有达到我预期的效果?
原始列表 project_keys = Sorted(projects.keys())
为 [101, 102, 103, 104, 105, 106, 107, 108, 109, 110]
其中今年以下项目被视为无效
: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
块上使用列表理解?简明?看起来更好看?
The original list project_keys = sorted(projects.keys())
is [101, 102, 103, 104, 105, 106, 107, 108, 109, 110]
where the following projects were deemed invalid
this year: 108, 109, 110.
Thus:
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
This will return a list of integers (which are project id's) as such:
[101, 102, 103, 104, 105, 106, 107]
Sweet.
Now, I wanted it try the same thing using a list comprehension.
project_keys = [project_keys.remove(project.proj_id) for project in projects.itervalues() if project.invalid
print project_keys
This returns:
[None, None, None]
So I'm populating a list with the same number as the removed elements but they're None
s?
Can someone point out what I'm doing wrong?
Additionally, why would I use a list comprehension over the for-if
block at the top? Conciseness? Looks nicer?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的列表理解使用副作用进行工作。只需执行它就应该更新 project_keys 以给出您想要的结果。
remove
的返回值为None
。将列表理解的结果分配给project_keys
是错误的地方。不过,这里一个简单的循环可能会更清晰。使用副作用的列表理解可能会令人困惑。
但是,您可以以稍微不同的方式解决您的问题:
这会保留您感兴趣的项目,而不是删除您不感兴趣的项目。上面给出的示例使用生成器表达式而不是列表理解,但它可以与任何一个一起使用。
Your list comprehension works using side-effects. Just executing it should update project_keys to give the result you want.
The return value from
remove
isNone
. Assigning the result of the list comprehension toproject_keys
is where you are going wrong.A simple loop is probably clearer here though. A list comprehension that uses side-effects can be confusing.
However you can solve your problem in a slightly different way:
This keeps the projects you are interested in, instead of removing those that you're not interested in. The example I gave above uses a generator expression instead of a list comprehension, but it would work with either.
先生,您误解了列表理解。
你可能想要什么(用文字表达)
你写的内容
实际发生的情况
实际发生的情况(现在有更多“功能”)
正如您所看到的,列表推导式不是
for
循环周围的语法糖。相反,列表推导式是围绕map()
和filter()
:将函数应用于序列中与条件匹配的所有项目,并获取返回的列表结果。这里,函数实际上是指输入到输出的无副作用转换。这意味着您“不能”使用更改输入本身的方法,例如
list.sort()
;您必须使用它们的等效功能,例如sorted()
。然而,我所说的“不能”并不意味着您会收到错误消息或 鼻恶魔;我的意思是你在滥用语言。在您的情况下,当您将列表理解分配给变量时发生的评估确实会产生预期的副作用 - 但它是否会在预期的变量上产生副作用?
看,它可以执行而不会出现错误的唯一原因是,在此列表理解之前,有另一个列表称为
project_keys
,它就是那个列表你真的在改变!列表推导式是函数式编程的结果,它拒绝副作用。使用列表推导式时请记住这一点。
因此,您可以使用以下思考过程来实际获得所需的列表理解。
你真正想要什么(用言语)
你真正想要什么
你真正想要什么(现在功能更强大)
你真正想要什么(现在作为列表理解)
You, sir, have misunderstood list comprehensions.
What you probably wanted (in words)
What you wrote
What is actually going on
What is actually going on (now with more "functional")
As you can see, list comprehensions are not syntactical sugar around
for
loops. Rather, list comprehensions are syntactical sugar aroundmap()
andfilter()
: apply a function to all items in a sequence that match a condition and get a list of results in return.Here, by function it is actually meant a side-effect-free transformation of input into output. This means that you "cannot" use methods that change the input itself, like
list.sort()
; you'll have to use their functional equivalents, likesorted()
.By "cannot", however, I don't mean you'll get error messages or nasal demons; I mean you are abusing the language. In your case, the evaluation of the list comprehension that happens as you assign it to a variable does indeed produce the intended side-effects -- but does it produce them on the intended variables?
See, the only reason why this can execute without an error is that before this list comprehension, there was another list called
project_keys
and it's that list you are actually changing!Lists comprehensions are a result of functional programming, which rejects side effects. Keep that in mind when using lists comprehensions.
So here's a thought process you can use to actually get the list comprehension you wanted.
What you actually wanted (in words)
What you actually wanted
What you actually wanted (now with more functional)
What you actually wanted (now as a list comprehension)