Python 循环:如何符合惯用法地比较列表中的相邻元素

6 投票
5 回答
4946 浏览
提问于 2025-04-15 18:35

我需要遍历一个对象列表,比较它们,比如:0和1,1和2,2和3,依此类推。(我在用pysvn提取差异列表。)最后我选择了用索引来循环,但我一直在想有没有更符合Python习惯的写法。毕竟这是Python,难道我不应该用一些聪明的迭代器吗?单纯用索引循环虽然很清晰,但我在想有没有更简洁或者更有表现力的方法来做到这一点。

for revindex in xrange(len(dm_revisions) - 1):
    summary = \
        svn.diff_summarize(svn_path,
                          revision1=dm_revisions[revindex],
                          revision2 = dm_revisions[revindex+1])

5 个回答

3

那么多复杂的解决方案被发布,为什么不简单点呢?

myList = range(5)

for idx, item1 in enumerate(myList[:-1]):
    item2 = L[idx + 1]
    print item1, item2

>>> 
0 1
1 2
2 3
3 4
4

我可能会这样做:

import itertools
for rev1, rev2 in zip(dm_revisions, itertools.islice(dm_revisions, 1, None)):
    summary = svn.diff_sumeraize(svn_python, revision1=rev, revision2=rev2)

还有一些更聪明的方法,可以不直接操作迭代器本身,可能会用到

13

这被称为滑动窗口。这里有一个在 itertools 文档中的示例,可以实现这个功能。以下是代码:

from itertools import islice

def window(seq, n=2):
    "Returns a sliding window (of width n) over data from the iterable"
    "   s -> (s0,s1,...s[n-1]), (s1,s2,...,sn), ...                   "
    it = iter(seq)
    result = tuple(islice(it, n))
    if len(result) == n:
        yield result    
    for elem in it:
        result = result[1:] + (elem,)
        yield result

这样的话,你可以这样说:

for r1, r2 in window(dm_revisions):
    summary = svn.diff_summarize(svn_path, revision1=r1, revision2=r2)

当然,你只关心 n=2 的情况,所以你可以用更简单的方式来处理:

def adjacent_pairs(seq):
    it = iter(seq)
    a = it.next()
    for b in it:
        yield a, b
        a = b

for r1, r2 in adjacent_pairs(dm_revisions):
    summary = svn.diff_summarize(svn_path, revision1=r1, revision2=r2)

撰写回答