2016-04-11 2 views
4

Я хочу знать, если есть более Pythonic способ сделать следующее:Pythonic способ сравнения всех соседних элементов в списке

A = some list 
i = 0 
j = 1 
for _ in range(1, len(A)): 
    #some operation between A[i] and A[j] 
    i += 1 
    j += 1 

Я чувствую, что это должно/может быть сделано по-разному. Идеи?

EDIT: Поскольку некоторые из нас просят требования. Я хотел получить ответ общего назначения. Возможно, проверить, что A [i], A [j] находятся между определенным диапазоном или если они равны. Или, может быть, я хотел сделать «струйку» элементов. Чем более общим, тем лучше.

+0

Вам нужен доступ к индексам списка или будет выполняться только по элементам без индексов для вас? –

ответ

1

zip позволяет объединить несколько итераторов:

for i,j in zip(range(0,len(A)-1), range(1,len(A))): 
    #some operation between A[i] and A[j] 

вы также можете использовать enumerate на объекте диапазон:

for i,j in enumerate(range(1,len(A)): 
    #some operation between A[i] and A[j] 

Обратите внимание, что в отличие от другие ответы дают вам доступ к в Обломки из А не только элементов, это необходимо, если вы хотите использовать назначение в A[i] или A[j], например, здесь очень простой пузырьковой сортировки:

A = list(range(10)) 
found1=True 
while found1: 
    found1=False 
    for i,j in enumerate(range(1,len(A))): 
     if A[i] < A[j]: 
      A[i],A[j] = A[j],A[i] 
      found1=True 
print(A) 

это только возможно, когда вы перебирать индексов А.

0

Вы можете сделать:

A = some list 
for Ai, Aj in zip(A, A[1:]): 
    #some operation between A[i] and A[j] 
+0

вы больше не итерируете по индексам, а элементы в A –

+0

Да, но если цель состоит в том, чтобы выполнить некоторую операцию между Ai и Aj, она работает. –

+0

'zip' - хорошая идея здесь, предполагая, что вам не нужны индексы Ai и Aj. Вы также можете сбрить несколько символов, выполнив 'zip (A, A [1:])'. Когда 'zip' получает два итератора разной длины, он выполняет только итерацию до конца более короткого.Поэтому резка последнего элемента с помощью 'A [: - 1]' не является строго необходимой. – Kevin

3

Для работы '+':

A = [A[i+1]+A[i] for i in range(len(A)-1)] 

Общие сведения:

A = [operation(A[i], A[i+1]) for i in range(len(A)-1)] 
6

Там хороший маленький рецепт в itertools для этого. В качестве бонуса он работает с любыми итерабельными, а не только с последовательностями.

from itertools import tee 

def pairwise(iterable): 
    "s -> (s0,s1), (s1,s2), (s2, s3), ..." 
    a, b = tee(iterable) 
    next(b, None) 
    return zip(a, b) 

for current, next_ in pairwise(A): 
    # do something 
    pass 

Если вам нужен индекс, а затем просто enumerate парной итератор.

for current_index, (current, next_) in enumerate(pairwise(A)): 
    # do something 
    pass 
+0

Каковы возвращаемые значения для перечисления. сильно смущен. это индекс, значение. Как перечисляет информацию, является ли это индексом, значением или значением и значением nextvalue. ? – AAI

+0

@ В любом случае вы можете проверить справку для перечисления с помощью 'help (enumerate)', в котором подробно описано, как работает перечисление. Он всегда дает последовательность 2-х кортежей 'index, element_at_index'. Тем не менее, я также распаковываю 'element_at_index' в' current' и 'next_' (потому что это то, что производит' pairwise'). – Dunes

0
from itertools import islice 
A1 = iter(A) 
A2 = islice(A,1) 
for a1, a2 in zip(A1, A2): 
    # do whatever with A[i], A[i+1] 

Вы можете использовать обычный ломтик A[1:], но это делает другой список атрофии памяти. Теперь zip() испускает значения до shortest Итератор (A2) исчерпан. Поэтому не стоит беспокоиться о возможном IndexError.