Як переглядати всі, крім останнього пункту списку?


160

Я хотів би переглядати список, що перевіряє кожен елемент, а не той, що йде за ним.

Чи є спосіб я провести цикл через усі, крім останнього, за допомогою x in y? Я вважаю за краще робити це без використання індексів, якщо можу.

Примітка

freespace відповів на моє фактичне запитання, саме тому я прийняв відповідь, але SilentGhost відповів на питання, яке я повинен був задати.

Вибачення за плутанину.

Відповіді:


316
for x in y[:-1]

Якщо yце генератор, то вищезгадане не буде працювати.


Це відповідає на моє запитання, дякую, але я забув запитати, як я отримаю предмет після x. Чи можливо це?
Девід Сайкс

3
- 1 Я не думаю, що це відповідає на питання. Не порівнюється кожен елемент із наступним. - odwl 0 сек. Тому
odwl

4
Я думаю, що так і зробив. Автор сказав, що він хотів би зробити X, потім запитав, як він може робити Y. Я відповів, як він може робити Y. Що він прийняв мою відповідь, це означатиме, що я відповів на його запитання, якщо не на питання, яке він насправді хотів задати. Аскер може продемонструвати цю відповідь.
простір

7
Тільки тому, що ОП повинен був задати ще одне запитання, це не означає, що його питання та ця відповідь не дуже корисні для інших. +1
Проф. Фолкен

1
Ви згадуєте, що це не працює для генераторів. Яка альтернатива, коли yгенератор?
Joost

50

найпростіший спосіб порівняння елемента послідовності з наступним:

for i, j in zip(a, a[1:]):
     # compare i (the current) to j (the following)

15
Це відповідає на питання, яке я хотів би поставити. Спасибі
Девід Сайкс

3
Насправді, ви можете опустити перший фрагмент, оскільки zip скорочує довший список на довжину коротшого. Це допоможе вам зберегти одне створення списку. (Про всяк випадок, коли ви маєте справу з величезними списками. Але в такому випадку вам слід дотримуватися підходу Антів Аасма, який нічого не копіює.)
bayer

19

Якщо ви хочете розумно розібратися в усіх елементах пари послідовностей, використовуйте цей підхід (функція попарно - з прикладів у модулі itertools).

from itertools import tee, izip, chain

def pairwise(seq):
    a,b = tee(seq)
    b.next()
    return izip(a,b)

for current_item, next_item in pairwise(y):
    if compare(current_item, next_item):
        # do what you have to do

Якщо вам потрібно порівняти останнє значення з якимось спеціальним значенням, ланцюжте це значення до кінця

for current, next_item in pairwise(chain(y, [None])):

зауважте, що використання наступного для вбудованих тіней змінних імен
SilentGhost

1
Я особисто не заперечую затінення менш вживаних вбудованих файлів, коли область застосування змінної невелика, а назва добре для читабельності. Тим не менш, редагували імена змінних, щоб підтримувати добрі практики кодування.
Мурахи Аасма

5

якщо ви мали на увазі порівняння n-го елемента з n + 1-м пунктом у списку, з яким ви також могли б поступити

>>> for i in range(len(list[:-1])):
...     print list[i]>list[i+1]

зауважте, що там не відбувається жорсткого кодування. Це повинно бути нормально, якщо ви не відчуваєте іншого.


3
Ви можете замінити len (список [: - 1]) на len (список) - 1, щоб уникнути копії списку. І уникайте використання змінної списку під назвою ...
Ремі Бланк

2

Щоб порівняти кожен елемент із наступним в ітераторі, не створюючи екземпляр списку:

import itertools
it = (x for x in range(10))
data1, data2 = itertools.tee(it)
data2.next()
for a, b in itertools.izip(data1, data2):
  print a, b

2
що саме то , що було запропоновано Мурахи Aasma stackoverflow.com/questions/914715 / ...
SilentGhost

1

Це дає відповідь на те, що повинен був запитати ОП , тобто провести список зіставлення послідовних елементів (відмінна відповідь SilentGhost ), але узагальнений для будь-якої групи ( n-грам ): 2, 3, ... n:

zip(*(l[start:] for start in range(0, n)))

Приклади:

l = range(0, 4)  # [0, 1, 2, 3]

list(zip(*(l[start:] for start in range(0, 2)))) # == [(0, 1), (1, 2), (2, 3)]
list(zip(*(l[start:] for start in range(0, 3)))) # == [(0, 1, 2), (1, 2, 3)]
list(zip(*(l[start:] for start in range(0, 4)))) # == [(0, 1, 2, 3)]
list(zip(*(l[start:] for start in range(0, 5)))) # == []

Пояснення:

  • l[start:] генерує список / генератор, починаючи з індексу start
  • *listабо *generator: передає всі елементи до функції, що додає, zipяк ніби вона була написанаzip(elem1, elem2, ...)

Примітка:

AFAIK, цей код такий самий ледачий, як це може бути. Не перевірений.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.