Найкоротший спосіб нарізати парні / непарні рядки з масиву python?


79

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


1
я усвідомлюю, що можу це зробити в циклі, але мені було цікаво, чи не міг би я зробити це в один рядок замість цього
fatcat

Гарне питання. Відповіді тут мені теж допомогли. Чудово, мерсі.
Сія

Відповіді:


167

Припускаючи, що ви говорите про список , ви вказуєте крок у зрізі (і індекс запуску). Синтаксис є list[start:end:step].

Напевно, ви знаєте звичайний доступ до списку для отримання елемента, наприклад, l[2]для отримання третього елемента. Даючи два числа і двокрапку між ними, ви можете вказати діапазон, який ви хочете отримати зі списку. Повернене значення - це інший список. Наприклад, l[2:5]ви отримуєте третій-шостий пункт. Ви також можете передати необов’язкове третє число, яке вказує розмір кроку. Розмір кроку за замовчуванням - один, що просто означає взяти кожен елемент (між початковим та кінцевим індексом).

Приклад:

>>> l = range(10)
>>> l[::2]         # even  - start at the beginning at take every second item
[0, 2, 4, 6, 8]
>>> l[1::2]        # odd - start at second item and take every second item
[1, 3, 5, 7, 9]

Див. Списки в підручнику з Python .

Якщо ви хочете отримати кожен n елемент списку (тобто, виключаючи перший елемент), вам доведеться нарізати як l[(n-1)::n].

Приклад:

>>> l = range(20)
>>> l
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

Тепер отримуємо кожен третій елемент:

>>> l[2::3]
[2, 5, 8, 11, 14, 17]

Якщо ви хочете включити перший елемент, ви просто це зробите l[::n].


Я ще ніколи цього не бачив. Перше число - це початковий індекс, а останнє - це крок? Щось йде між ::? Або обидва вони є оператором, який відрізняється від :? Якщо я l[::1]отримаю вихідний масив, тоді?
fatcat

1
@fatcat - docs.python.org/library/… , див. примітки 3 та 5
Джеремі Браун

@fatcat: Так, ви отримаєте оригінальний масив. Я б сказав, що частіше ви бачите лише фрагмент від початкового до кінцевого індексу, наприклад l[2:5]. Крок необов’язковий.
Фелікс Клінг

1

Це більше для мене як повний приклад;)

>>> import itertools
>>> ret = [[1,2], [3,4,5,6], [7], [8,9]]
>>> itertools.izip_longest(*ret)
>>> [x for x in itertools.chain.from_iterable(tmp) if x is not None]
[1, 3, 7, 8, 2, 4, 9, 5, 6]

-1
> map(lambda index: arr[index],filter(lambda x: x%n == 0,range(len(arr))))

де arrсписок, і nфрагменти потрібні.


1
-1 для використання map()та filter()за допомогою lambda. Це не рекомендується / повільно, і це завжди слід робити, використовуючи розуміння списку.
ThiefMaster

1
Чи існують експерименти для підтвердження цієї заяви?
ajmartin

1
Думаю, десь в архіві списків розсилки python є про це довідник з guideo van rossum. У будь-якому випадку, це наче очевидно, оскільки це виклик функції проти відсутності виклику функції. Якщо ви не використовуєте функції виклику Stackless, що є досить дорогим
ThiefMaster
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.