如何遍历列表中除最后一项以外的所有内容?

问题:如何遍历列表中除最后一项以外的所有内容?

我想遍历一个列表,将每个项目与它后面的项目进行对照。

有没有一种方法可以遍历除最后一项以外的所有项,以便在y中使用x?如果可以的话,我宁愿不使用索引就这样做。

注意

freespace回答了我的实际问题,这就是为什么我接受答案,但是SilentGhost回答了我应该问的问题。

抱歉造成混乱。

I would like to loop through a list checking each item against the one following it.

Is there a way I can loop through all but the last item using for x in y? I would prefer to do it without using indexes if I can.

Note

freespace answered my actual question, which is why I accepted the answer, but SilentGhost answered the question I should have asked.

Apologies for the confusion.


回答 0

for x in y[:-1]

如果y是生成器,则以上操作将无效。

for x in y[:-1]

If y is a generator, then the above will not work.


回答 1

比较序列项与以下内容的最简单方法:

for i, j in zip(a, a[1:]):
     # compare i (the current) to j (the following)

the easiest way to compare the sequence item with the following:

for i, j in zip(a, a[1:]):
     # compare i (the current) to j (the following)

回答 2

如果要成对获取序列中的所有元素,请使用此方法(成对函数来自itertools模块中的示例)。

from itertools import tee, izip, chain

def pairwise(seq):
    a,b = tee(seq)
    b.next()
    return izip(a,b)

for current_item, next_item in pairwise(y):
    if compare(current_item, next_item):
        # do what you have to do

如果需要将最后一个值与某个特殊值进行比较,则将该值链接到末尾

for current, next_item in pairwise(chain(y, [None])):

If you want to get all the elements in the sequence pair wise, use this approach (the pairwise function is from the examples in the itertools module).

from itertools import tee, izip, chain

def pairwise(seq):
    a,b = tee(seq)
    b.next()
    return izip(a,b)

for current_item, next_item in pairwise(y):
    if compare(current_item, next_item):
        # do what you have to do

If you need to compare the last value to some special value, chain that value to the end

for current, next_item in pairwise(chain(y, [None])):

回答 3

如果您要比较列表中的第n个项目和第n + 1个项目,则也可以使用

>>> for i in range(len(list[:-1])):
...     print list[i]>list[i+1]

请注意,那里没有硬编码。除非您另有感觉,否则应该可以。

if you meant comparing nth item with n+1 th item in the list you could also do with

>>> for i in range(len(list[:-1])):
...     print list[i]>list[i+1]

note there is no hard coding going on there. This should be ok unless you feel otherwise.


回答 4

要在迭代器中将每个项目与下一个项目进行比较而不实例化列表:

import itertools
it = (x for x in range(10))
data1, data2 = itertools.tee(it)
data2.next()
for a, b in itertools.izip(data1, data2):
  print a, b

To compare each item with the next one in an iterator without instantiating a list:

import itertools
it = (x for x in range(10))
data1, data2 = itertools.tee(it)
data2.next()
for a, b in itertools.izip(data1, data2):
  print a, b

回答 5

这回答了OP 应该问的问题,即遍历比较连续元素的列表(出色的SilentGhost答案),但对任何组(n-gram)都可以推广:2、3,… n

zip(*(l[start:] for start in range(0, n)))

例子:

l = range(0, 4)  # [0, 1, 2, 3]

list(zip(*(l[start:] for start in range(0, 2)))) # == [(0, 1), (1, 2), (2, 3)]
list(zip(*(l[start:] for start in range(0, 3)))) # == [(0, 1, 2), (1, 2, 3)]
list(zip(*(l[start:] for start in range(0, 4)))) # == [(0, 1, 2, 3)]
list(zip(*(l[start:] for start in range(0, 5)))) # == []

说明:

  • l[start:] 从索引开始生成一个列表/生成器 start
  • *list*generator:将所有元素传递给封闭函数zip,就好像它被编写一样zip(elem1, elem2, ...)

注意:

AFAIK,此代码尽可能地懒惰。未经测试。

This answers what the OP should have asked, i.e. traverse a list comparing consecutive elements (excellent SilentGhost answer), yet generalized for any group (n-gram): 2, 3, … n:

zip(*(l[start:] for start in range(0, n)))

Examples:

l = range(0, 4)  # [0, 1, 2, 3]

list(zip(*(l[start:] for start in range(0, 2)))) # == [(0, 1), (1, 2), (2, 3)]
list(zip(*(l[start:] for start in range(0, 3)))) # == [(0, 1, 2), (1, 2, 3)]
list(zip(*(l[start:] for start in range(0, 4)))) # == [(0, 1, 2, 3)]
list(zip(*(l[start:] for start in range(0, 5)))) # == []

Explanations:

  • l[start:] generates a a list/generator starting from index start
  • *list or *generator: passes all elements to the enclosing function zip as if it was written zip(elem1, elem2, ...)

Note:

AFAIK, this code is as lazy as it can be. Not tested.