我想搜索一个列表:
[0, 0, 1, 0, 1, 1, 1, 0, 1, 1]
并替换/编辑与上一项和下一项不同的项目。对于xxample:我想删除/编辑上面列表中索引2处的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会将下一个项目读为double,因为我在循环中使用了next(hiter
)两次。
我也尝试过声明像y = next(hiter)
这样的单独变量 - 但它仍然无法工作(显然不会工作但我无论如何都非常想检查xD)。
我没有线索,此外,hiter.__next__()
与next(hiter)
的做法相同。
答案 0 :(得分:3)
你自己太复杂了。相反,只需在循环中多次阅读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))
答案 1 :(得分:3)
您可以使用一个生成器来保留前一个项目并提前查看一个项目:
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
注意:两种方法都会创建一个新列表,并且不会修改原始列表。
答案 2 :(得分:1)
您可能希望通过索引访问列表元素。在循环中,您可以通过添加或减去当前索引来访问上一个和下一个项目。
请注意,在列表中,您可以使用@PatchMapping("/addresses/{id}/{repository}")
public Resource<Address> update(PersistentEntityResource addressResource) {
...
}
,hiter[0]
,...访问元素,并在循环中访问:
hiter[1]
然后您可以访问上一个和下一个,只需要处理边缘情况(以防止索引超出范围)。方法是:
for i in range(len(hiter)-1):
print("The item is %s" % hiter[i])
以相同的方式,您可以使用相同的索引方法更改可变列表中的值。
答案 3 :(得分:-1)
有一个itertools.tee功能,可以克隆&#34;克隆&#34;迭代器。
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]
答案 4 :(得分:-1)
!更新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)