理解与范围界定有一些意想不到的相互作用.这是预期的行为吗?
我有一个方法:
def leave_room(self, uid):
u = self.user_by_id(uid)
r = self.rooms[u.rid]
other_uids = [ouid for ouid in r.users_by_id.keys() if ouid != u.uid]
other_us = [self.user_by_id(uid) for uid in other_uids]
r.remove_user(uid) # OOPS! uid has been re-bound by the list comprehension above
# Interestingly, it's rebound to the last uid in the list, so the error only shows
# up when len > 1
Run Code Online (Sandbox Code Playgroud)
冒着抱怨的风险,这是一个残酷的错误来源.当我编写新代码时,我偶尔会发现由于重新绑定而导致非常奇怪的错误 - 即使现在我知道这是一个问题.我需要制定一个规则,比如"总是用下划线列出列表推导中的临时变量",但即使这样也不是万无一失的.
这种随机定时炸弹等待的事实否定了列表理解的所有"易用性".
我想知道是否有更好的方法来打印Python列表中的所有对象,而不是:
myList = [Person("Foo"), Person("Bar")]
print("\n".join(map(str, myList)))
Foo
Bar
Run Code Online (Sandbox Code Playgroud)
我读这种方式并不是很好:
myList = [Person("Foo"), Person("Bar")]
for p in myList:
print(p)
Run Code Online (Sandbox Code Playgroud)
是不是有类似的东西:
print(p) for p in myList
Run Code Online (Sandbox Code Playgroud)
如果没有,我的问题是......为什么?如果我们可以用综合列表来做这种事情,为什么不把它作为列表之外的简单陈述呢?
我在Python中有一些列表理解,其中每次迭代都会抛出异常.
例如,如果我有:
eggs = (1,3,0,3,2)
[1/egg for egg in eggs]
Run Code Online (Sandbox Code Playgroud)
我会ZeroDivisionError在第3个元素中得到一个例外.
如何处理此异常并继续执行列表推导?
我能想到的唯一方法是使用辅助函数:
def spam(egg):
try:
return 1/egg
except ZeroDivisionError:
# handle division by zero error
# leave empty for now
pass
Run Code Online (Sandbox Code Playgroud)
但这对我来说看起来有点麻烦.
有没有更好的方法在Python中执行此操作?
注意: 这是我设计的一个简单示例(参见上面的" 例如 "),因为我的真实示例需要一些上下文.我不想避免除零错误,而是处理列表理解中的异常.
你怎么打破一个很长的列表理解?
[something_that_is_pretty_long for something_that_is_pretty_long in somethings_that_are_pretty_long]
Run Code Online (Sandbox Code Playgroud)
我也看到过某些人不喜欢使用'\'来分解线条,但却从不理解为什么.这背后的原因是什么?
想想我正在调用它的副作用的函数,而不是返回值(比如打印到屏幕,更新GUI,打印到文件等).
def fun_with_side_effects(x):
...side effects...
return y
Run Code Online (Sandbox Code Playgroud)
现在,是Pythonic使用列表推导来调用这个函数:
[fun_with_side_effects(x) for x in y if (...conditions...)]
Run Code Online (Sandbox Code Playgroud)
请注意,我不会将列表保存在任何位置
或者我应该像这样调用这个函数:
for x in y:
if (...conditions...):
fun_with_side_effects(x)
Run Code Online (Sandbox Code Playgroud)
哪个更好?为什么?
我想比较2个iterables并打印出两个iterables中出现的项目.
>>> a = ('q', 'r')
>>> b = ('q')
# Iterate over a. If y not in b, print y.
# I want to see ['r'] printed.
>>> print([ y if y not in b for y in a])
^
Run Code Online (Sandbox Code Playgroud)
但是它给了我一个无效的语法错误^.这个lamba函数有什么问题?
为了做相当于Python列表的理解,我正在做以下事情:
some_array.select{|x| x % 2 == 0 }.collect{|x| x * 3}
Run Code Online (Sandbox Code Playgroud)
有没有更好的方法来做到这一点......也许有一个方法调用?
我熟悉"矢量化"的概念,以及熊猫如何使用矢量化技术来加速计算.矢量化函数在整个系列或DataFrame上广播操作,以实现比传统迭代数据更大的加速.
但是,我很惊讶地看到很多代码(包括Stack Overflow的答案)提供了解决问题的方法,这些问题涉及使用for循环和列表推导来循环数据.阅读完文档后,对API有了不错的理解,我认为循环是"坏的",并且应该"永远"迭代数组,系列或DataFrame.那么,为什么我会不时地看到用户提出循环解决方案呢?
因此,要总结......我的问题是:
是否for循环真正的"坏"?如果不是,在什么情况下它们会比使用更传统的"矢量化"方法更好?1
1 - 虽然这个问题确实听起来有点宽泛,但事实是,当for循环通常比传统的迭代数据更好时,存在非常具体的情况.这篇文章旨在为后人捕捉这一点.
我有两个列表如下
tags = [u'man', u'you', u'are', u'awesome']
entries = [[u'man', u'thats'],[ u'right',u'awesome']]
Run Code Online (Sandbox Code Playgroud)
我想从entries它们进入时提取条目tags:
result = []
for tag in tags:
for entry in entries:
if tag in entry:
result.extend(entry)
Run Code Online (Sandbox Code Playgroud)
如何将两个循环写为单行列表理解?
我正在玩列表推导,我在另一个网站上看到了这个小片段:
return ''.join([`num` for num in xrange(loop_count)])
Run Code Online (Sandbox Code Playgroud)
我花了几分钟试图复制这个函数(通过输入),然后才意识到`num`它正在破坏它.
在这些字符中包含语句的内容是什么?从我所看到的它相当于str(num).但是当我计时:
return ''.join([str(num) for num in xrange(10000000)])
Run Code Online (Sandbox Code Playgroud)
它需要4.09s而:
return ''.join([`num` for num in xrange(10000000)])
Run Code Online (Sandbox Code Playgroud)
需要2.43秒.
两者都给出了相同的结果,但其中一个慢得多.这里发生了什么?
编辑:奇怪... repr()给出稍微慢一点的结果`num`.2.99s vs 2.43s.使用Python 2.6(尚未尝试过3.0).