2008-11-27 2 views

ответ

0

Итераторы имеют следующий() метод, поэтому вы не можете смотреть вперед или назад, вы можете получить только следующий предмет.

enumerate (iterable) может быть полезна, если вы повторяете список или кортеж.

-7

Самый простой способ найти список артикулов:

def get_previous(l, item): 
    idx = l.find(item) 
    return None if idx == 0 else l[idx-1] 

Конечно, это работает только, если список содержит только уникальные элементы. Другое решение:

for idx in range(len(l)): 
    item = l[idx] 
    if item == 2: 
     l[idx-1] 
1

Я не думаю, что есть простой способ, тем более, что итератор может быть генератором (не возвращается). Там достойный обходной путь, опираясь на явно передавая индекс в теле цикла:

for itemIndex, item in enumerate(l): 
    if itemIndex>0: 
     previousItem = l[itemIndex-1] 
    else: 
     previousItem = None 

enumerate() функция является встроенной.

61

Выраженный как функция генератора:

def neighborhood(iterable): 
    iterator = iter(iterable) 
    prev_item = None 
    current_item = next(iterator) # throws StopIteration if empty. 
    for next_item in iterator: 
     yield (prev_item, current_item, next_item) 
     prev_item = current_item 
     current_item = next_item 
    yield (prev_item, current_item, None) 

Использование:

for prev,item,next in neighborhood(l): 
    print prev, item, next 
+1

Я мог бы сделать «prev, item = item, next» в этом случае. – 2008-11-27 17:31:55

+1

Чтобы сделать этот цикл бесконечно (без StopIteration), сделайте `из цикла импорта itertools` и измените вторую строку на:` iterator = cycle (iterable) ` – 2009-12-17 01:50:04

+0

Разве это меньше Pythonic, чтобы использовать перечисление в этом контексте? – batbrat 2014-02-27 06:40:13

6

При работе с генераторами, где вам нужен некоторый контекст, я часто использует ниже функцию полезности, чтобы дать скользящий вид окна на итератор:

import collections, itertools 

def window(it, winsize, step=1): 
    """Sliding window iterator.""" 
    it=iter(it) # Ensure we have an iterator 
    l=collections.deque(itertools.islice(it, winsize)) 
    while 1: # Continue till StopIteration gets raised. 
     yield tuple(l) 
     for i in range(step): 
      l.append(it.next()) 
      l.popleft() 

Он сгенерирует представление последовательности N элементов в точке ime, переместившись на несколько ступеней. например.

>>> list(window([1,2,3,4,5],3)) 
[(1, 2, 3), (2, 3, 4), (3, 4, 5)] 

При использовании в опережающем просмотре/за ситуациями, где вы также должны иметь дело с цифрами, не имея следующее или предыдущее значение, вы можете набивать последовательность с соответствующим значением, например, как None.

l= range(10) 
# Print adjacent numbers 
for cur, next in window(l + [None] ,2): 
    if next is None: print "%d is the last number." % cur 
    else: print "%d is followed by %d" % (cur,next) 
0

Непосредственно предыдущий?

Вы имеете в виду следующее, не так ли?

previous = None 
for item in someList: 
    if item == target: break 
    previous = item 
# previous is the item before the target 

Если вы хотите п предыдущих пунктов, вы можете сделать это с какой-то круговой очереди размером п.

queue = [] 
for item in someList: 
    if item == target: break 
    queue .append(item) 
    if len(queue) > n: queue .pop(0) 
if len(queue) < n: previous = None 
previous = previous[0] 
# previous is *n* before the target 
9
l=[1,2,3] 
for i,item in enumerate(l): 
    if item==2: 
     get_previous=l[i-1] 
     print get_previous 

>>>1 
5

Заканчивать утилиту петлителя от Tempita project. Он предоставляет объект-обертку вокруг элемента цикла, который предоставляет такие свойства, как предыдущий, следующий, первый, последний и т. Д.

Посмотрите на класс петлителя , это довольно просто. Есть другие подобные помощники цикла, но я не могу вспомнить других сейчас.

Пример:

> easy_install Tempita 
> python 
>>> from tempita import looper 
>>> for loop, i in looper([1, 2, 3]): 
...  print loop.previous, loop.item, loop.index, loop.next, loop.first, loop.last, loop.length, loop.odd, loop.even 
... 
None 1 0 2 True False 3 True 0 
1 2 1 3 False False 3 False 1 
2 3 2 None False True 3 True 0 
-2

Не очень вещий, но получает это сделать и просто:

l=[1,2,3] 
for index in range(len(l)): 
    if l[index]==2: 
     l[index-1] 

ДЕЛАТЬ: защитить края

5

Я знаю, что это старый, но почему не просто использовать enumerate?

l = ['adam', 'rick', 'morty', 'adam', 'billy', 'bob', 'wally', 'bob', 'jerry'] 

for i, item in enumerate(l): 
    if i == 0: 
     previous_item = None 
    else: 
     previous_item = l[i - 1] 

    if i == len(l) - 1: 
     next_item = None 
    else: 
     next_item = l[i + 1] 

    print('Previous Item:', previous_item) 
    print('Item:', item) 
    print('Next Item:', next_item) 
    print('') 

    pass 

Если вы запустите это, вы увидите, что он захватывает предыдущие и следующие элементы и не заботится о повторении элементов в списке.

21

Один простой способ.

l=[1,2,3] 
for i,j in zip(l, l[1:]): 
    print i, j 
0

Если вы хотите, чтобы решение работать на итерируемых, то itertools' docs есть рецепт, который делает именно то, что вы хотите:

import itertools 

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

Если вы используете Python 2.x, используйте itertools.izip вместо zip

Смежные вопросы