Python - 如何使用几次相同的下一次迭代?
Python - how to use few times the same next iteration?
我要搜索列表:
[0, 0, 1, 0, 1, 1, 1, 0, 1, 1]
和replace/edit项不同于上一项和下一项。对于 xxample:我想删除上面列表中索引 2 处的 of/edit 1
。
看看我下面的代码,请继续阅读我的代码下面的核心问题:
!更新: 结果应该是:[0, 0, 0, 0, 1, 1, 1, 1, 1, 1]
x = [0, 0, 1, 0, 1, 1, 1, 0, 1, 1]
print(x)
hiter = iter(x)
next(hiter)
prev = None
for i in x:
try:
print('prev %s - CURRENT %s - next %s' % (prev, i, next(hiter)))
prev = i
#if i != prev and i != next(hiter):
# x[i] = prev
except StopIteration:
break
print(x)
我们知道上一项、下一项和当前项目。
但每次我使用:
if i != prev and i != next(hiter)...
next(hiter)
破坏秩序。换句话说,如果我在循环中使用 next(hiter)
超过 1 次,Python 会将下一项读取为双精度,因为我在循环中使用了两次 next(hiter
)。
我也试过像 y = next(hiter)
这样声明单独的变量 - 但它仍然没有用(显然不会用,但我还是很想检查它 xD)。
我没有线索,另外,hiter.__next__()
和next(hiter)
一样。
你把事情搞得太复杂了。相反,只需在循环中多次阅读 x
:
for idx in range(1, len(x)-1): # Consider using enumerate, it's a great idea
curr = x[idx]
prev = x[idx - 1]
nxt = x[idx + 1]
if (curr != prev) and (curr != nxt):
print('prev %s - CURRENT %s - next %s' % (prev, curr, nxt))
有一个 itertools.tee 函数允许 "clone" 个迭代器。
iter1, iter2 = itertools.tee(iter(<iterable>))
你的案例看起来太琐碎了 - 除非它只是例子,否则就使用它
编辑
那样的话
for index, val in enumerate(x[1:-1], 1)
if val != x[index-1] and val != x[index+1]:
x[index] = x[index-1]
您可以使用一个生成器来保留前一项并向前看一项:
def gen(x):
x = iter(x)
# Get the first item and simply yield it
first = next(x)
yield first
# create a list containing the previous element, the current element and the next element
# and iterate over your input.
three = [None, first, next(x)]
for item in x:
# Update the list of elements: Remove the previous previous item and
# add the new next item.
three = three[1:] + [item]
prev, cur, nxt = three
if cur != prev and cur != nxt:
three[1] = prev # replace the current item with the previous item
yield prev
else:
yield cur
# Simply yield the last item
yield three[-1]
>>> list(gen([0, 0, 1, 0, 1, 1, 1, 0, 1, 1]))
[0, 0, 0, 0, 1, 1, 1, 1, 1, 1]
在这种方法中,我只是返回了第一项和最后一项而不进行检查,因为只有下一项或上一项,而不是两者。如果你愿意,你也可以在那里放一些支票。
正如@MadPhysicist 指出的那样,根本不需要列表,您可以简单地为 previous
、current
和 next
项使用一个变量:
def gen(x):
x = iter(x)
# Get the first item and simply yield it
first = next(x)
yield first
cur, nxt = first, next(x) # Initial current and next item
for item in x:
prev, cur, nxt = cur, nxt, item # Update the previous, current and next item
if cur != prev and cur != nxt:
cur = prev
yield prev
else:
yield cur
# Simply yield the last item
yield nxt
注意:这两种方法都会创建一个新列表,不会修改原始列表。
您可能想通过索引访问您的列表元素。在您的循环中,您可以通过添加或减去当前索引来访问上一个和下一个项目。
请记住,在列表中,您可以使用 hiter[0]
、hiter[1]
、...访问元素,并在循环中作为:
for i in range(len(hiter)-1):
print("The item is %s" % hiter[i])
因此您可以访问上一个和下一个,只需要处理边缘情况(以防止索引超出范围)。一种方法是:
for i in range(len(hiter)):
if 0 < i < (len(hiter) - 1):
print("The items are %s, %s, %s" % (hiter[i-1], hiter[i], hiter[i+1]))
elif i == 0:
print("The items are %s, %s" % (hiter[i], hiter[i+1]))
elif i == (len(hiter) - 1):
print("The items are %s, %s" % (hiter[i-1], hiter[i]))
以同样的方式,您可以使用相同的索引方法更改可变列表中的值。
!更新 2: 感谢大家的贡献。这真的很有帮助,我今天学到了很多东西。这就是我的意思(抱歉@MSeifert,但我必须按照自己的方式去做,我知道生成器速度更快,而且它们不会占用内存)。
解决方案:
x = [0, 0, 1, 0, 1, 1, 1, 0, 1, 1]
print(x)
for i in range(1, len(x)-1):
current = x[i]
nxt = x[i+1]
prev = x[i-1]
if current != prev and current != nxt:
print('prev: %s - CURRENT: %s - next: %s [ X ]' % (prev, current, nxt))
x[i] = x[i-1]
else:
print('prev: %s - CURRENT: %s - next: %s' % (prev, current, nxt))
print(x)
我要搜索列表:
[0, 0, 1, 0, 1, 1, 1, 0, 1, 1]
和replace/edit项不同于上一项和下一项。对于 xxample:我想删除上面列表中索引 2 处的 of/edit 1
。
看看我下面的代码,请继续阅读我的代码下面的核心问题:
!更新: 结果应该是:[0, 0, 0, 0, 1, 1, 1, 1, 1, 1]
x = [0, 0, 1, 0, 1, 1, 1, 0, 1, 1]
print(x)
hiter = iter(x)
next(hiter)
prev = None
for i in x:
try:
print('prev %s - CURRENT %s - next %s' % (prev, i, next(hiter)))
prev = i
#if i != prev and i != next(hiter):
# x[i] = prev
except StopIteration:
break
print(x)
我们知道上一项、下一项和当前项目。
但每次我使用:
if i != prev and i != next(hiter)...
next(hiter)
破坏秩序。换句话说,如果我在循环中使用 next(hiter)
超过 1 次,Python 会将下一项读取为双精度,因为我在循环中使用了两次 next(hiter
)。
我也试过像 y = next(hiter)
这样声明单独的变量 - 但它仍然没有用(显然不会用,但我还是很想检查它 xD)。
我没有线索,另外,hiter.__next__()
和next(hiter)
一样。
你把事情搞得太复杂了。相反,只需在循环中多次阅读 x
:
for idx in range(1, len(x)-1): # Consider using enumerate, it's a great idea
curr = x[idx]
prev = x[idx - 1]
nxt = x[idx + 1]
if (curr != prev) and (curr != nxt):
print('prev %s - CURRENT %s - next %s' % (prev, curr, nxt))
有一个 itertools.tee 函数允许 "clone" 个迭代器。
iter1, iter2 = itertools.tee(iter(<iterable>))
你的案例看起来太琐碎了 - 除非它只是例子,否则就使用它
编辑 那样的话
for index, val in enumerate(x[1:-1], 1)
if val != x[index-1] and val != x[index+1]:
x[index] = x[index-1]
您可以使用一个生成器来保留前一项并向前看一项:
def gen(x):
x = iter(x)
# Get the first item and simply yield it
first = next(x)
yield first
# create a list containing the previous element, the current element and the next element
# and iterate over your input.
three = [None, first, next(x)]
for item in x:
# Update the list of elements: Remove the previous previous item and
# add the new next item.
three = three[1:] + [item]
prev, cur, nxt = three
if cur != prev and cur != nxt:
three[1] = prev # replace the current item with the previous item
yield prev
else:
yield cur
# Simply yield the last item
yield three[-1]
>>> list(gen([0, 0, 1, 0, 1, 1, 1, 0, 1, 1]))
[0, 0, 0, 0, 1, 1, 1, 1, 1, 1]
在这种方法中,我只是返回了第一项和最后一项而不进行检查,因为只有下一项或上一项,而不是两者。如果你愿意,你也可以在那里放一些支票。
正如@MadPhysicist 指出的那样,根本不需要列表,您可以简单地为 previous
、current
和 next
项使用一个变量:
def gen(x):
x = iter(x)
# Get the first item and simply yield it
first = next(x)
yield first
cur, nxt = first, next(x) # Initial current and next item
for item in x:
prev, cur, nxt = cur, nxt, item # Update the previous, current and next item
if cur != prev and cur != nxt:
cur = prev
yield prev
else:
yield cur
# Simply yield the last item
yield nxt
注意:这两种方法都会创建一个新列表,不会修改原始列表。
您可能想通过索引访问您的列表元素。在您的循环中,您可以通过添加或减去当前索引来访问上一个和下一个项目。
请记住,在列表中,您可以使用 hiter[0]
、hiter[1]
、...访问元素,并在循环中作为:
for i in range(len(hiter)-1):
print("The item is %s" % hiter[i])
因此您可以访问上一个和下一个,只需要处理边缘情况(以防止索引超出范围)。一种方法是:
for i in range(len(hiter)):
if 0 < i < (len(hiter) - 1):
print("The items are %s, %s, %s" % (hiter[i-1], hiter[i], hiter[i+1]))
elif i == 0:
print("The items are %s, %s" % (hiter[i], hiter[i+1]))
elif i == (len(hiter) - 1):
print("The items are %s, %s" % (hiter[i-1], hiter[i]))
以同样的方式,您可以使用相同的索引方法更改可变列表中的值。
!更新 2: 感谢大家的贡献。这真的很有帮助,我今天学到了很多东西。这就是我的意思(抱歉@MSeifert,但我必须按照自己的方式去做,我知道生成器速度更快,而且它们不会占用内存)。
解决方案:
x = [0, 0, 1, 0, 1, 1, 1, 0, 1, 1]
print(x)
for i in range(1, len(x)-1):
current = x[i]
nxt = x[i+1]
prev = x[i-1]
if current != prev and current != nxt:
print('prev: %s - CURRENT: %s - next: %s [ X ]' % (prev, current, nxt))
x[i] = x[i-1]
else:
print('prev: %s - CURRENT: %s - next: %s' % (prev, current, nxt))
print(x)