Доступ к элементам со смещением в циклах Python for .. in

Я немного возился с Python и понял, что обычно лучше (или «pythonic») использовать

for x in SomeArray:

а не более C-стиль

for i in range(0, len(SomeArray)):

Я вижу преимущества в этом, в основном в более чистом коде и в возможности использовать хорошие map() и связанные с ними функции. Однако я довольно часто сталкиваюсь с ситуацией, когда я хотел бы одновременно обращаться к элементам с разными смещениями в массиве. Например, мне может понадобиться добавить текущий элемент к элементу, находящемуся на два шага позади него. Есть ли способ сделать это, не прибегая к явным индексам?


person int3    schedule 15.08.2009    source источник
comment
Обратите внимание, что range(0, len(SomeArray)) эквивалентен более обычному диапазону (len(SomeArray)).   -  person Eric O Lebigot    schedule 15.08.2009


Ответы (2)


Способ сделать это в Python:

for i, x in enumerate(SomeArray):
    print i, x

Генератор enumerate создает последовательность из двух кортежей, каждый из которых содержит индекс массива и элемент.

person Greg Hewgill    schedule 15.08.2009
comment
Но как мне получить доступ к предыдущим/последующим элементам за одну итерацию цикла? - person int3; 15.08.2009
comment
Внутри цикла вы можете получить доступ к SomeArray[i-1] или SomeArray[i+1]. - person Greg Hewgill; 15.08.2009
comment
SomeArray[i-1]? Но вы можете объяснить, что вы на самом деле делаете - person SilentGhost; 15.08.2009
comment
Поскольку у вас есть индекс текущего элемента в i, вы можете получить доступ к элементам вокруг него, добавляя или вычитая некоторое смещение из i и получая доступ к элементу в этой позиции. - person Greg Hewgill; 15.08.2009

Индексация списка и zip() — ваши друзья.

Вот мой ответ на ваш более конкретный вопрос:

Я мог бы добавить текущий элемент к элементу на два шага позади него. Есть ли способ сделать это, не прибегая к явным индексам?

arr = range(10)
[i+j for i,j in zip(arr[:-2], arr[2:])]

Вы также можете использовать модуль numpy, если собираетесь работать с числовыми массивами. Например, приведенный выше код можно более элегантно записать так:

import numpy
narr = numpy.arange(10)
narr[:-2] + narr[2:]

Добавление n-го элемента к (n-2)-му эквивалентно добавлению m-го элемента к (m+2) элементу (для математически подкованных мы сделали замену n->m+2). Диапазон n равен [2, len(arr)), а диапазон m равен [0, len(arr)-2). Обратите внимание на скобки и круглые скобки. Элементы от 0 до len(arr)-3 (вы исключаете последние два элемента) индексируются как [:-2], а элементы от 2 до len(arr)-1 (вы исключаете первые два элемента) индексируются как [ 2:].

Я предполагаю, что вы уже знакомы со списками.

person Christian Alis    schedule 15.08.2009
comment
да, я знаю понимание списка. хотя особо ими не пользовался. zip() выглядит как еще одно хорошее решение, спасибо! - person int3; 15.08.2009