Извлечь элементы списка в нечетные позиции


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: Зачем ему нужно перечислять понимания в вопросе?
Tamara Wijsman

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

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

Ответы:


231

Решение

Да, ты можешь:

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 посмотрите на этот вопрос, чтобы понять синтаксис нарезки python
Preet Kukreti

Вопрос требует нечетных позиций. Это дает равные позиции (0,2,4,6); похоже, что OP хочет индексов (1,3,5), которые будут заданы [1,2,3,4,5,6,7][1::2].
Marcin

@Marcin: Да, я действительно пришел к такому же выводу (см. Исправление). Это появилось после того, как я внимательно прочитал код OP. Проблема возникла из-за другой базы для индексации (для меня « нечетный » элемент означал первый элемент, для OP, казалось бы, он был вторым , поэтому индексировался в 1).
Tadeck

1
@TomWijsman: Простите, я не заметил, что вы изменили. Действительно, ссылка есть, но она ведет к проекту Numarray, а не к listнарезке Python . Он немного отличается, особенно потому, что listсрез не сохраняет ссылку на исходный список (в Numarray вам нужно явно вызвать, .copy()чтобы что-то не ссылалось на исходный массив). Но приятно иметь то, что может быть лучше для некоторых читателей. Не могли бы вы разместить эту ссылку в комментарии, чтобы я мог проголосовать за нее, и она появится сразу под ответом?
Tadeck

@Tadeck "Нечетные индексы" естественным образом означает индексы, которые являются нечетными числами.
Marcin

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
Разве это не должно быть enumerate (L) вместо enumerate (items)?
ab123

0

Вы можете использовать побитовый оператор AND &. Посмотрим ниже:

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

Поразрядный оператор И используется с 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

Операция AND с 1 вернет только 1 (1 в двоичном формате также будет иметь последнюю цифру 1), если значение нечетное.

Посетите страницу Python Bitwise Operator для получения дополнительной информации.

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

список_ = список (диапазон (9)) печать (список_ [1 :: 2])


пожалуйста, ответьте кратким объяснением и поместите некоторые блоки кода правильно отформатированными. Спасибо
венката кришнан
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.