从python中的for循环返回值
Posted
技术标签:
【中文标题】从python中的for循环返回值【英文标题】:Returns values from a for loop in python 【发布时间】:2011-07-05 08:19:44 【问题描述】:我正在尝试找出在 for 循环语法中将参数从一个列表或字典传递到另一个的语法。
我想要的结果是这样的:
for bean in beans:
if bean.type == 'coffee':
print bean
只是,我想收集该字符串数据并将其附加到另一个列表,而不是打印到标准输出。最终使列表变平。
踢球者,我想在一行中执行此操作。
我知道''.join()
方法,我正在寻找这个结果,以便我可以过滤来自for-in 循环的结果。
【问题讨论】:
【参考方案1】:[bean for bean in beans if bean.type == 'coffee']
List comprehensions 很整洁。更简洁的是,您通常不需要生成整个列表 - 您只需要一个迭代器来为您提供列表将包含的值。那是一个生成器,它们可以通过生成器表达式简洁地表达。它们的编写方式与列表推导相同,只是方括号变成了括号(如果它是函数调用中的唯一参数,您可以省略它们)例如'\n'.join(str(bean) for bean in beans if bean.type == 'coffee')
。优点是提到的惰性,即在真正需要(请求)它们之前您永远不会生成值,并且您不会同时将所有它们都保存在内存中(当然,除非消费者这样做)。
您可以使用itertools.chain
将多个可迭代对象(包括列表)链接到一个,或者如果您无法更改获取列表列表的事实,您可以使用(x for list in lists for x in list)
。对于涉及 abritary 深度嵌套的通用解决方案,您需要一个利用递归的完整函数。
【讨论】:
由于列表是内置的,因此可能希望避免使用同名变量。 @Adeel:一般来说是正确的(如果您提出好的建议,我会进行编辑 - 除了非常神秘的xs
,我想不出任何通用名称)。不过这里的问题不大,因为生成器表达式不会将迭代变量泄漏到外部(不再)。
关于 Python 3 修复列表推导中循环控制变量的泄漏问题是绝对正确的。只有我们这些仍在使用 Python 2 的人才需要担心这个问题。【参考方案2】:
单行将使用列表或生成器推导,请参阅 Blair 的回答。
对您当前代码的修改将适合 yield 关键字,它允许您构造这样的生成器函数:
def coffee_filter(beans):
for bean in beans:
if bean.type == 'coffee':
yield bean
for bean in coffee_filter(beans):
print "coffee from %s" % bean.country
由于 python 允许您在几乎任何地方定义函数,这非常有用。
【讨论】:
在 90% 的情况下,编写一个完整的生成器是多余的。这也不例外。如果生成器表达式有效,就这样吧。 我有点惊讶您没有使用生成器表达式作为方法的内部结构。我不建议删除该功能 - 如果没有别的,它会凭借其名称提供文档(这很可爱,即使您的答案质量较低,也会为您赢得 +1 ......)跨度> @Blair:名称很容易添加(确实是个好主意):只需定义filtered_coffee = <genexpr>
并使用它而不是内联它;)
@delnan @Blair:我在写这篇文章之前只阅读了部分问题,错过了单行部分,所以我只是将代码转换为 yield 而不是打印。 (我后来在编辑中添加了第一句话。)【参考方案3】:
'\n'.join([str(bean) for bean in beans if bean.type == 'coffee'])
【讨论】:
您可以跳过 [] 并获取生成器表达式。这样可以避免构建中间列表。 @Macke,很公平。我远离 Python 解释器,不想冒险 str.join() 不接受迭代 - 我以前被想要列表的东西所困扰。再说一次,这可能是 .Net 污染了我的大脑...... 请放心,在 Python 中,所有可能接受 abritary iterables 的东西都会。除非当然是由一个可怜的灵魂写的,他不知道for i in range(len(list))
是谁...以上是关于从python中的for循环返回值的主要内容,如果未能解决你的问题,请参考以下文章
为啥我的 For 循环在 EJS 节点 js 中只返回一个值?