Я должен циклично выполниться по списку объектов, сравнив их как это: 0 по сравнению с 1, 1 по сравнению с 2, 2 по сравнению с 3, и т.д. (Я использую pysvn для извлечения списка diffs.) Я волновал просто цикличное выполнение по индексу, но я продолжаю задаваться вопросом, существует ли некоторый способ сделать это, который более тесно идиоматичен. Это - Python; разве я не должен использовать итераторы некоторым умным способом? Просто цикличное выполнение по индексу кажется довольно четким, но интересно, существует ли более выразительный или краткий способ сделать это.
for revindex in xrange(len(dm_revisions) - 1):
summary = \
svn.diff_summarize(svn_path,
revision1=dm_revisions[revindex],
revision2 = dm_revisions[revindex+1])
Это называется раздвижным окном. В документации [111815] есть пример 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)
Храните предыдущее значение в переменной. Инициализируйте переменную со значением, которое вы вряд ли найдете в последовательности, которую вы обрабатываете, поэтому вы можете знать, если вы находитесь на первом элементе. Сравните старое значение к текущей стоимости.
Ну, вы делаете это, потому что все разные браузеры знают, как строка, которая составляет URL, кодируется. Преобразование пространства до% 20 и т. Д. Сделает этот URL / URI портативный. Это может быть латин-1, это может быть Unicode. Нужно нормализовано к чему-то, что понимается универсально. Посмотрите на RFC3986 http://tools.ietf.org/html/rfc3986#section-2.1
-121--1257654-Уменьшить можно использовать для этой цели, если вы берегите К Оставьте копию текущего элемента в результате восстановительной функции .
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, [])
Редактировать: Да, но никто не сказал результат функции в Уменьшить
должен быть скалярным. Я изменил свой пример, чтобы использовать список. В основном, последний элемент всегда является предыдущим пересмотром (кроме первого прохода), со всеми предыдущими элементами являются результаты 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']
Это было проверено в оболочке, как вы можете видеть. Вы захотите заменить (PREV, NXT)
в LST.Append
Call . Сравните
, чтобы фактически добавить сводку вызова на 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.
Я бы, наверное, сделаю:
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)
что-то аналогично умнее и не трогать самих итераторов, вероятно, может быть сделано
Так много сложных решений, привязанных, почему бы не держать его простой?
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