我需要遍历一个对象列表,比较它们:0对1,1对2,2对3等等(我正在使用pysvn来提取差异列表。)I最后只是循环索引,但我一直想知道是否有某种方法可以做到这一点更贴近惯用语。这是Python;我不应该以某种聪明的方式使用迭代器吗?简单地循环遍历索引似乎很清楚,但我想知道是否有更具表现力或简洁的方法来做到这一点。
for revindex in xrange(len(dm_revisions) - 1):
summary = \
svn.diff_summarize(svn_path,
revision1=dm_revisions[revindex],
revision2 = dm_revisions[revindex+1])
答案 0 :(得分:13)
这称为滑动窗口。有一个example in the itertools
documentation可以做到这一点。这是代码:
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)
答案 1 :(得分: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)
同样聪明且没有触及迭代器本身的东西可能是使用
完成的答案 2 :(得分: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
答案 3 :(得分:0)
将先前的值存储在变量中。使用您在处理的序列中找不到的值初始化变量,这样您就可以知道您是否处于第一个元素。将旧值与当前值进行比较。
答案 4 :(得分:-1)
如果您注意在缩小功能的结果中留下当前项目的副本,则可以使用缩小。
def diff_summarize(revisionList, nextRevision):
'''helper function (adaptor) for using svn.diff_summarize with reduce'''
if revisionList:
# remove the previously tacked on item
r1 = revisionList.pop()
revisionList.append(svn.diff_summarize(
svn_path, revision1=r1, revision2=nextRevision))
# tack the current item onto the end of the list for use in next iteration
revisionList.append(nextRevision)
return revisionList
summaries = reduce(diff_summarize, dm_revisions, [])
编辑:是的,但是没有人说reduce
中的函数结果必须是标量。我改变了我的例子以使用列表。基本上,最后一个元素是前一个修订版(第一遍除外),所有前面的元素都是svn.diff_summarize
调用的结果。这样,您可以获得结果列表作为最终输出...
EDIT2:是的,代码确实被破坏了。我这里有一个可行的假人:
>>> def compare(lst, nxt):
... if lst:
... prev = lst.pop()
... lst.append((prev, nxt))
... lst.append(nxt)
... return lst
...
>>> reduce(compare, "abcdefg", [])
[('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'e'), ('e', 'f'), ('f', 'g'), 'g']
你可以看到,这是在shell中测试过的。您需要在(prev, nxt)
lst.append
的{{1}}来电中替换compare
,以实际将呼叫摘要附加到svn.diff_summarize
。
>>> help(reduce)
Help on built-in function reduce in module __builtin__:
reduce(...)
reduce(function, sequence[, initial]) -> value
Apply a function of two arguments cumulatively to the items of a sequence,
from left to right, so as to reduce the sequence to a single value.
For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
((((1+2)+3)+4)+5). If initial is present, it is placed before the items
of the sequence in the calculation, and serves as a default when the
sequence is empty.