繁体   English   中英

Python:对没有 if 子句的非空列表的迭代结果为空。 为什么?

[英]Python: an iteration over a non-empty list with no if-clause comes up empty. Why?

没有过滤和聚合( sum()等)的非空序列上的迭代器怎么能不产生任何结果?

考虑一个简单的例子:

sequence = ['a', 'b', 'c']
list((el, ord(el)) for el in sequence)

如预期的那样,这会产生[('a', 97), ('b', 98), ('c', 99)]

现在,只需将ord(el)替换为使用(...).next()从某个生成器中取出第一个值的表达式——请原谅人为的示例:

def odd_integers_up_to_length(str):
    return (x for x in xrange(len(str)) if x%2==1)

list((el, odd_integers_up_to_length(el).next()) for el in sequence)

这产生[] 是的,空列表。 没有('a', stuff )元组。 没有什么。

但我们没有过滤、聚合或减少。 没有过滤或聚合的n对象的生成器表达式必须产生n对象,对吗? 这是怎么回事?

odd_integers_up_to_length(el).next()将引发 StopIteration,它没有被捕获,但被捕获用于其中的生成器表达式,停止它而不产生任何东西。

查看第一次迭代,当值为“a”时:

>>> odd_integers_up_to_length('a').next()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

发生的情况是next()调用引发了一个StopIteration异常,该异常使堆栈冒泡到外部生成器表达式并停止迭代。

StopIteration是迭代器发出完成信号的正常方式。 通常我们看不到它,因为通常next()调用发生在使用迭代器的构造中,例如for x in iteratorsum(iterator) 但是当我们直接调用next()时,我们是负责捕获StopIteration的人。 不这样做会在抽象中引发泄漏,这会导致外部迭代中出现意外行为。

我想,教训是:小心直接调用next()

str 是一个保留的关键字,你应该以不同的方式命名你的变量

我也建议下一个

>>> seq=['a','b','c']
>>> list((el,4) for el in seq)
[('a',4), ('b',4), ('c',4)]

所以这里不是给你带来麻烦的list ......

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM