Список Python: Как прочитать предыдущий элемент при использовании для цикла? [Дубликат]
Но я хочу получить предыдущий элемент i, как это сделать? Мне не нужно использовать цикл for, поэтому не стесняйтесь ничего менять. Спасибо!
7 ответов
Обычно вы используете enumerate или range() для прохождения элементов. Здесь альтернатива
>>> li = [2,31,321,41,3423,4,234,24,32,42,3,24,31,123] >>> zip(li[1:],li) [(31, 2), (321, 31), (41, 321), (3423, 41), (4, 3423), (234, 4), (24, 234), (32, 24), (42, 32), (3, 42), (24, 3), (31, 24), (123, 31)]
второй элемент каждого кортежа является предыдущим элементом списка.
Да, это работает, но если ваш список очень большой, вы действительно хотите снизить производительность, создав второй действительно большой список (с помощью li[1:] )?
Я уже сказал, что это альтернатива. Конечно, если список действительно большой, не используйте этот метод. просто как тот.
вы можете использовать zip:
for a, b in zip(li, li[1:]): print a, b
или, если вам нужно сделать что-то немного странное, потому что создание списка или взятие фрагмента li будет неэффективным (по какой-то причине. ),
import itertools readahead = iter(li) next(readahead) for a, b in itertools.izip(li, readahead) print a, b
+1 за ответ itertools, не первый. Первое хорошо, если список маленький, но если список действительно большой, создание копии будет неэффективным.
Просто отслеживайте индекс и получайте предыдущий элемент по индексу
li = range(10) for i, item in enumerate(li): if i > 0: print item, li[i-1] print "or. " for i in range(1,len(li)): print li[i], li[i-1]
1 0 2 1 3 2 4 3 5 4 6 5 7 6 8 7 9 8 or. 1 0 2 1 3 2 4 3 5 4 6 5 7 6 8 7 9 8
другой альтернативой является запоминание последнего элемента, например.
last_item = None for item in li: print last_item, item last_item = item
Опция, использующая рецепт itertools здесь:
from itertools import tee def pairwise(iterable): "s -> (s0,s1), (s1,s2), (s2, s3), . " a, b = tee(iterable) next(b, None) return izip(a, b) for i, j in pairwise(li): print i, j
@martineau: не много. Единственная реальная разница — это использование tee . Они достигают разных вещей. Ответ @ TokenMacGuy не работает, если li является общим итератором, а не списком, он пропускает пары. Вот почему здесь используется tee . Я больше пытался привлечь внимание к красивым рецептам itertools ( pairwise копируется оттуда), а не изобретать велосипед.
Используйте счетчик циклов в качестве индекса. (Обязательно начинайте с одного, чтобы оставаться в зоне действия.)
for i in range(1,len(li)): print li[i], li[i-1]
How to access the previous/next element in a for loop? [duplicate]
Is there a way to access a list ‘s (or tuple ‘s, or other iterable’s) next or previous element while looping through it with a for loop?
l = [1, 2, 3] for item in l: if item == 2: get_previous(l, item)
15 Answers 15
Expressed as a generator function:
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
To make this cycle infinitely (no StopIteration), do from itertools import cycle and change the second line to: iterator = cycle(iterable)
The answer you’re looking for is Vicky Liau’s, the one below this one. Or, if you want it to work on any iterable and not just lists/tuples/strs etc, the one using itertools .
For python 3.10 — users there is ready to go function itertools.pairwise, see stackoverflow.com/a/69584524/3361462
l = [1, 2, 3] for i, j in zip(l, l[1:]): print(i, j)
I used this, but expanded to avoid dropping the start/end items: for prev,cur,next in zip([None]+l[:-1], l, l[1:]+[None]):
You can avoid dropping the start/end items like this: l = [None, *l, None] and then for prev, cur, nxt in zip(l, l[1:], l[2:]):
l = [1, 2, 3] for i, item in enumerate(l): if item == 2: previous = l[i - 1] print(previous)
This will wrap around and return the last item in the list if the item you’re looking for is the first item in list. In other words changing the third line to if item == 1: in the above code will cause it to print 3 .
If your list is only one element long l = [2] , this will return the same element as the previous element.
When dealing with generators where you need some context, I often use the below utility function to give a sliding window view on an iterator:
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()
It’ll generate a view of the sequence N items at a time, shifting step places over. eg.
>>> list(window([1,2,3,4,5],3)) [(1, 2, 3), (2, 3, 4), (3, 4, 5)]
When using in lookahead/behind situations where you also need to deal with numbers without having a next or previous value, you may want pad the sequence with an appropriate value such as 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)
If you’re using itertools , use Francisco Couzo’s answer with itertools.tee instead: stackoverflow.com/a/41047005
I know this is old, but why not just use 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
If you run this you will see that it grabs previous and next items and doesn’t care about repeating items in the list.
The question also asked for the previous item. And won’t this work incorrectly if an item repeats? [1,2,1,3] ?
Check out the looper utility from the Tempita project. It gives you a wrapper object around the loop item that provides properties such as previous, next, first, last etc.
Take a look at the source code for the looper class, it is quite simple. There are other such loop helpers out there, but I cannot remember any others right now.
> 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
If you want the solution to work on iterables, the itertools documentation has a recipe that does exactly what you want using itertools.tee() :
import itertools def pairwise(iterable): "s -> (s0,s1), (s1,s2), (s2, s3), . " a, b = itertools.tee(iterable) next(b, None) return zip(a, b)
If you don’t want to import anything, here is an example of accessing the previous item of a generator with the for loop. It uses a class variable to store each next result before the following next call. This variable could be a small list if you wanted more than the immediately previous item. Inside the class is a method generator that effectively extends the next() builtin to include the previous item assignment.
def previous(): class Plusprev(): def __init__(pp, gen=None): pp.g = gen pp.nxt = '' pp.prev = 'start' def ppnext(pp): while pp.nxt != 'done': pp.nxt = next(pp.g,'done') yield pp.nxt pp.prev = pp.nxt sqgen = (n*n for n in range(13)) ppcl = Plusprev(sqgen) nxtg = ppcl.ppnext() nxt = next(nxtg,'done') while nxt != 'done': print('\nprevious ',ppcl.prev) print('current ',nxt) nxt = next(nxtg,'done') previous()
This uses the builtin function, next(), default parameter.
Списки (list). Функции и методы списков
Сегодня я расскажу о таком типе данных, как списки, операциях над ними и методах, о генераторах списков и о применении списков.
Что такое списки?
Списки в Python — упорядоченные изменяемые коллекции объектов произвольных типов (почти как массив, но типы могут отличаться).
Чтобы использовать списки, их нужно создать. Создать список можно несколькими способами. Например, можно обработать любой итерируемый объект (например, строку) встроенной функцией list:
Список можно создать и при помощи литерала:
Как видно из примера, список может содержать любое количество любых объектов (в том числе и вложенные списки), или не содержать ничего.
И еще один способ создать список — это генераторы списков. Генератор списков — способ построить новый список, применяя выражение к каждому элементу последовательности. Генераторы списков очень похожи на цикл for.
Возможна и более сложная конструкция генератора списков:
Но в сложных случаях лучше пользоваться обычным циклом for для генерации списков.
Функции и методы списков
Создать создали, теперь нужно со списком что-то делать. Для списков доступны основные встроенные функции, а также методы списков.
Таблица «методы списков»
Метод | Что делает |
---|---|
list.append(x) | Добавляет элемент в конец списка |
list.extend(L) | Расширяет список list, добавляя в конец все элементы списка L |
list.insert(i, x) | Вставляет на i-ый элемент значение x |
list.remove(x) | Удаляет первый элемент в списке, имеющий значение x. ValueError, если такого элемента не существует |
list.pop([i]) | Удаляет i-ый элемент и возвращает его. Если индекс не указан, удаляется последний элемент |
list.index(x, [start [, end]]) | Возвращает положение первого элемента со значением x (при этом поиск ведется от start до end) |
list.count(x) | Возвращает количество элементов со значением x |
list.sort(Предыдущий элемент массива python) | Сортирует список на основе функции |
list.reverse() | Разворачивает список |
list.copy() | Поверхностная копия списка |
list.clear() | Очищает список |
Нужно отметить, что методы списков, в отличие от строковых методов, изменяют сам список, а потому результат выполнения не нужно записывать в эту переменную.
И, напоследок, примеры работы со списками:
Изредка, для увеличения производительности, списки заменяют гораздо менее гибкими массивами (хотя в таких случаях обычно используют сторонние библиотеки, например NumPy).
Для вставки кода на Python в комментарий заключайте его в теги
- Книги о Python
- GUI (графический интерфейс пользователя)
- Курсы Python
- Модули
- Новости мира Python
- NumPy
- Обработка данных
- Основы программирования
- Примеры программ
- Типы данных в Python
- Видео
- Python для Web
- Работа для Python-программистов