Python - 如何在下一次迭代中使用几次?

时间:2017-06-06 14:49:34

标签: python list loops iterator next

我想搜索一个列表:

[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)的做法相同。

5 个答案:

答案 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所指出的那样,根本不需要列表,您只需使用previouscurrentnext项的变量:

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)