Витягніть елементи списку на непарних позиціях


100

Тому я хочу створити список, який є підспілом якогось існуючого списку.

Наприклад,

L = [1, 2, 3, 4, 5, 6, 7], Я хочу створити такий підпис li, який liмістить усі елементи у Lнепарних позиціях.

Поки я можу це зробити

L = [1, 2, 3, 4, 5, 6, 7]
li = []
count = 0
for i in L:
    if count % 2 == 1:
        li.append(i)
    count += 1

Але я хочу знати, чи є інший спосіб зробити те саме ефективно і за меншою кількістю кроків.


@WaleedKhan: Чому йому потрібно перераховувати розуміння питання?
Тамара Війсман

1
@TomWijsman: Список розумінь . ETA: Не зважайте на це: я полював навколо і виявив цю вашу відповідь, яка вказує на те, що ви жартуєте. Покладіть усміхнене обличчя наступного разу!
Девід Робінсон

2
@DavidRobinson: Але чи можуть інші люди сказати це, ОП може не зрозуміти, що він має на увазі двома неоднозначними словами. Просто колоти туди-сюди з деякими коментарями, щоб люди підготували та писали кращий вміст; і щоб уникнути безперебійного відвідування ОП або відвідувачів ... :)
Тамара Війсман

Відповіді:


229

Рішення

Так, ти можеш:

l = L[1::2]

І це все. Результат буде містити елементи, розміщені на наступних позиціях ( 0-основані, тому перший елемент знаходиться у положенні 0, другий у 1тощо):

1, 3, 5

тому результат (фактичні числа) буде:

2, 4, 6

Пояснення

В [1::2]кінці - це лише позначення для нарізки списку. Зазвичай він складається у такій формі:

some_list[start:stop:step]

Якщо ми пропустили start, 0буде використано default ( ). Отже, буде обраний перший елемент (у положенні 0, оскільки індекси - 0основи). У цьому випадку буде обраний другий елемент.

Оскільки другий елемент опущений, використовується за замовчуванням (кінець списку). Тож список повторюється від другого елемента до кінця .

Ми також надали третій аргумент ( step), який є 2. Що означає, що буде обраний один елемент, наступний буде пропущений і так далі ...

Отже, підводячи підсумок, у цьому випадку [1::2]означає:

  1. візьміть другий елемент (який, до речі, є непарним елементом, якщо судити з індексу),
  2. пропустити один елемент (тому що у нас є step=2, тому ми пропускаємо один, на відміну від step=1замовчування),
  3. взяти наступний елемент,
  4. Повторіть кроки 2.-3. до кінця списку,

EDIT : @PreetKukreti дав посилання на ще одне пояснення щодо позначення нарізки списку Python. Дивіться тут: Поясніть позначення фрагментів Python

Екстри - заміна лічильника на enumerate()

У своєму коді ви чітко створюєте та збільшуєте лічильник. У Python це не обов'язково, так як ви можете перерахувати через деякі ітерабельні, використовуючи enumerate():

for count, i in enumerate(L):
    if count % 2 == 1:
        l.append(i)

Вищезазначене служить точно тій самій цілі, що і код, який ви використовували:

count = 0
for i in L:
    if count % 2 == 1:
        l.append(i)
    count += 1

Детальніше про емуляцію forциклів з лічильником у Python: Доступ до індексу в циклі Python 'for'


@TomWijsman подивіться на це питання, щоб зрозуміти синтаксис нарізки пітона
Preet Kukreti

Питання задає непарні позиції. Це дає рівні позиції (0,2,4,6); це здається, що ОП хоче індекси (1,3,5), які були б задані [1,2,3,4,5,6,7][1::2].
Марцін

@Marcin: Так, я фактично вийшов з тим же висновком (див. Виправлення). Це з’явилося після того, як я уважно прочитав код ОП. Проблема спричинила різну базу для індексації (для мене " непарний " елемент означав перший елемент, для ОП, здавалося б, це другий , так індексований на 1).
Тадек

1
@TomWijsman: Вибачте, я не помітив, що ви змінили. Дійсно, є посилання, але це призводить до проекту Numarray, а не до listрозрізання Python . Це трохи відрізняється, тим більше, що listфрагмент 's не підтримує посилання на вихідний список (у Numarray потрібно чітко зателефонувати, .copy()щоб мати щось не посилається на початковий масив). Але приємно мати щось, що може бути кращим для деяких читачів. Ви б не хотіли розмістити це посилання в коментарі, тож я можу подати його, і воно з’явиться трохи нижче відповіді?
Тадек

@Tadeck "Непарні нумеровані індекси" досить природно означають індекси, які є непарними числами.
Марцін

12

Для непарних позицій ви, мабуть, хочете:

>>>> list_ = list(range(10))
>>>> print list_[1::2]
[1, 3, 5, 7, 9]
>>>>

3

Мені подобається розуміння списку через їх синтаксис Math (Set). То як щодо цього:

L = [1, 2, 3, 4, 5, 6, 7]
odd_numbers = [y for x,y in enumerate(L) if x%2 != 0]
even_numbers = [y for x,y in enumerate(L) if x%2 == 0]

В основному, якщо перерахувати список, ви отримаєте індекс xі значення y. Що я тут роблю, - це введення значення yу вихідний список (парне чи непарне) та використання індексу, xщоб з’ясувати, чи є ця точка непарною ( x%2 != 0).


1
Чи не слід це замінювати (L) замість нумерації (елементів)?
ab123

0

Ви можете скористатися побітним оператором AND &. Давайте подивимось нижче:

x = [1, 2, 3, 4, 5, 6, 7]
y = [i for i in x if i&1]
>>> 
[1, 3, 5, 7]

Побітовий оператор AND використовується з 1, і причина, в якій він працює, тому що непарне число, записане в двійковій формі, повинно мати свою першу цифру як 1. Давайте перевіримо

23 = 1 * (2**4) + 0 * (2**3) + 1 * (2**2) + 1 * (2**1) + 1 * (2**0) = 10111
14 = 1 * (2**3) + 1 * (2**2) + 1 * (2**1) + 0 * (2**0) = 1110

І операція з 1 поверне лише 1 (1 у двійковій буде також мати останню цифру 1), якщо значення буде непарним.

Перегляньте сторінку бітового оператора Python для отримання додаткової інформації.

PS: Ви можете тактично використовувати цей метод, якщо ви хочете вибрати непарні і парні стовпці в кадрі даних. Скажімо, x і y координати ключових точок обличчя наводяться у вигляді стовпців x1, y1, x2 тощо. Для нормалізації координат x і y з значеннями ширини та висоти кожного зображення ви можете просто виконати

for i in range(df.shape[1]):
    if i&1:
        df.iloc[:, i] /= heights
    else:
        df.iloc[:, i] /= widths

Це не зовсім пов’язано з питанням, але для науковців даних та інженерів комп'ютерного зору цей метод може бути корисним.

Ура!


-1

list_ = список (діапазон (9)) друк (список_ [1 :: 2])


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