python for循环,如何查找下一个值(对象)?

python for循环,如何查找下一个值(对象)?,python,for-loop,Python,For Loop,嗨,我正在尝试使用for循环通过减去彼此来找出每两个对象之间的差异。 那么,如何在for循环中找到下一个值呢 for entry in entries: first = entry # Present value last = ?????? # The last value how to say? diff = last = first 应该注意的是,这些解决方案中没有一个适用于发电机。为此,请参阅格伦·梅纳德卓越解决方案 对小列表使用zip: f

嗨,我正在尝试使用for循环通过减去彼此来找出每两个对象之间的差异。 那么,如何在for循环中找到下一个值呢

for entry in entries:
    first = entry      # Present value
    last = ??????      # The last value how to say?
    diff = last = first

应该注意的是,这些解决方案中没有一个适用于发电机。为此,请参阅格伦·梅纳德卓越解决方案

对小列表使用zip:

 for current, last in zip(entries[1:], entries):
     diff = current - last
这将创建列表的副本(以及列表两个副本中的元组列表),因此最好使用itertools来处理较大的列表

import itertools as it

items = it.izip(it.islice(entries, 1, None), entries)
for current, last in items:
    diff = current - last
这将避免复制列表和创建元组列表

另一种不用复印的方法是

entry_iter = iter(entries)
entry_iter.next() # Throw away the first version
for i, entry in enumerate(entry_iter):
    diff = entry - entries[i]
另一种方式是:

for i in xrange(len(entries) - 1):
    diff = entries[i+1] - entries[i]
这将创建一个迭代器,该迭代器索引
条目
,并将其前进一步。然后使用
enumerate
获取项目的标记。标记从0开始,因此指向上一个元素,因为我们在中循环一个项目

此外,正如泰勒在评论中指出的那样,对于这样一个简单的问题,如果您只想迭代这些差异,那么循环可能会有些过头

diffs = (current - last for current, last in 
         it.izip(it.islice(entries, 1, None), entries))

zip
适用于列表,但一般情况下:

def pairs(it):
    it = iter(it)
    prev = next(it)
    for v in it:
        yield prev, v
        prev = v

a = [1,2,3,4,5]
for prev, cur in pairs(a):
    print cur - prev

import itertools as it
for prev, cur in pairs(it.cycle([1,2,3,4])):
    print cur - prev
这对大型容器有效,更重要的是,它对迭代器有效:

for prev, cur in pairs(open("/usr/share/dict/words").xreadlines()):
    print cur, prev,

编辑:我将生成器更改为省略第一个值,而不使用以前的值,因为这更符合原始问题(“查找相邻对之间的差异”),并且我添加了一个示例案例,表明它适用于无限重复的迭代器。

非常简单,使用枚举,没有花哨的东西

>>> entries=[10,20,30,40]
>>> for n,i in enumerate(entries):
...     try:
...        print entries[n+1] - i
...     except IndexError:
...        print entries[-1]
...
10
10
10
40

我不知道你到底在看什么,但也许这能帮上忙:

first = entries[0]
for entry in entries[1:]:
    last = entry       
    diff = last - first 
    first = entry

为什么这需要一个循环?就我个人而言,我不建议在这样的情况下使用嵌套itertools:这不是很直观,需要一点眯着眼睛才能弄清楚它在做什么。编写一个简单的生成器函数更容易理解。请注意,这不适用于迭代器(如果您真的愿意,可以使用
itertools.tee
解决这个问题)。迭代器的优点很好。我一时对你的回答感到困惑。我猜直觉是在旁观者的眼里。一个有用的迭代器处理测试用例:
entries=itertools.cycle([1,2,3,4])
另一个添加到我越来越多的被接受的错误答案列表中的例子——亚伦,我无意冒犯你。这个网站的一个严重错误的设计假设是,提出问题的人有资格决定哪个答案是最好的。@Glenn,我同意他的观点。我删除了我的答案,但看到劣质的重复出现,所以我想,如果我取消删除,他们会停止。我的错误是认为写一张便条说明你的答案更好就足够了。也许下一次,我将尝试查看and标记是否仍然有效。我认为将
it
的第一个元素放在生成器中,而不是放在for循环中会更干净。@直觉:我这样做了,但在“让我访问以前的值”的一般情况下,这可能不是理想的行为。不管怎样,这取决于用户。这是一个糟糕的答案,因为[a]你会在每次使用中都用到除此之外的语句(这是昂贵的),而且[b](就像我删除的答案一样)它排除了使用一般序列的可能性,这可能会降低无法传入生成器但必须创建列表的大部分代码的效率。(也要求客户机代码了解所使用的任何函数的内部工作,从而彻底击败函数的要点)昂贵??你想要多便宜?超便宜?非常便宜的中等便宜?每次使用时,它只会命中except语句一次(如果发生)。我喜欢它,因为它简单易懂,没有什么花哨的东西。不,它每次都会出现(在上一次迭代中,
n+1
没有定义时)。此外,在这里使用
enumerate
非常不自然。您想要的是
范围内的i(len(entries)-1):打印条目[i+1]-条目[i]
,它简单易懂,没有什么特别的东西。但它在一般序列上仍然不起作用。@ghostdog74:在枚举(seq)中为
索引、值做:
,然后从不使用
值是不自然的。使用
n
作为索引,使用
i
作为值是不自然的**2。@john machin,你看,我已经使用了
i
。满意的?无论使用
n,i
是否是不自然的,我都将其留给OP。他应该足够明智,为他的变量使用专有名称。你们这些家伙很喜欢跳舞,不是吗。