迭代列表的for x in y:
的python语法必须以某种方式记住指针当前在哪个元素?当我试图解决这个问题而不诉诸for index, x in enumerate(y):
我想要这样做的技术原因是我假设enumerate()
会花费性能,而以某种方式访问已经存在的'指针'则不会。我从答案中看到,但是这个指针非常私密且无法访问。
我想要这样做的功能原因是,如果当前元素浮点值远离“期望的”浮点范围,则能够跳过例如100个元素。
- 答案 -
解决方法如下(纯示意图):
# foo is assumed to be ordered in this example
foo = [1,2,3,4,5,6....,99,100]
low = 60
high = 70
z = iter(foo)
for x in z:
if x < low-10
next(islice(z,10,10),None)
if x > high
break
答案 0 :(得分:7)
你做不到。 for
使用Python iteration protocol,对于列表,它意味着它将创建一个私有迭代器对象。该对象跟踪列表中的位置。
即使您使用iter()
显式创建迭代器,当前位置不该对象上的公共属性:
>>> list_iter = iter([])
>>> list_iter
<listiterator object at 0x10056a990>
>>> dir(list_iter)
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__iter__', '__length_hint__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'next']
迭代协议的要点在于,它允许您以完全相同的方式处理任何序列,即使是没有边界的序列。创建没有位置的序列生成器:
是微不足道的def toggle():
while True:
yield True
yield False
当您迭代它时,该生成器将在True
和False
值之间切换。那里的序列中没有位置,所以也没有任何一点暴露位置。
坚持enumerate()
。 enumerate()
所要做的就是保留一个计数器。它根本不会在包装的迭代器中保持位置。增加该整数不会花费你太多的性能或内存。
enumerate()
基本这个,implemented in C:
def enumerate(sequence, start=0):
n = start
for elem in sequence:
yield n, elem
n += 1
因为它是用C实现的,所以它会在任何一天尝试读取原始迭代器上的属性,这在每次迭代中都需要更多的字节码操作。
答案 1 :(得分:1)
不,它使用基础迭代器,不会强制跟踪当前索引。
除非你手动启动计数器,否则这是不可能的:
idx = 0
for x in y:
idx+=1
# ...
所以,请保持enumerate()
答案 2 :(得分:1)
该'指针'值是创建迭代器的内部函数。请记住,不需要是一个列表(可以编入索引的东西),所以如果你真的想要'索引',你将需要求助于使用枚举。
答案 3 :(得分:1)
此信息是迭代器的内部信息,无法访问。有关iterator protocol的说明,请参见此处。从本质上讲,迭代器中唯一可公开获得的成员是next()
,一旦范围用尽,就会引发StopIteration
异常。
此外,enumerate
效率很高。这相当于写作
i = -1
for x in y:
i += 1
# do something with x and i