Wyodrębnij elementy listy na nieparzystych pozycjach


100

Dlatego chcę utworzyć listę, która jest podlistą jakiejś istniejącej listy.

Na przykład,

L = [1, 2, 3, 4, 5, 6, 7]Chcę utworzyć podmenu litakie, że lizawiera wszystkie elementy Lw pozycjach nieparzystych.

Chociaż mogę to zrobić

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

Ale chcę wiedzieć, czy istnieje inny sposób, aby zrobić to samo wydajnie i w mniejszej liczbie kroków.


@WaleedKhan: Dlaczego w pytaniu musi wymieniać wyrażenia?
Tamara Wijsman

1
@TomWijsman: Lista wyrażeń . ETA: Zignoruj ​​to: szukałem w okolicy i odkryłem twoją odpowiedź, która wskazuje, że żartujesz. Następnym razem umieść uśmiechniętą buźkę!
David Robinson,

2
@DavidRobinson: Ale czy inni ludzie mogą to powiedzieć, dla OP może nie być jasne, co ma na myśli, używając dwóch niejednoznacznych słów. Po prostu dźganie tu i ówdzie komentarzami, żeby ludzie przygotowywali się i pisali lepsze treści; i aby uniknąć opuszczenia PO lub nieświadomych gości ... :)
Tamara Wijsman

Odpowiedzi:


230

Rozwiązanie

Tak, możesz:

l = L[1::2]

I to wszystko. Wynik będzie zawierał elementy umieszczone na następujących pozycjach ( 0oparte na podstawie, więc pierwszy element jest na pozycji 0, drugi na 1itd.):

1, 3, 5

więc wynik (rzeczywiste liczby) będzie:

2, 4, 6

Wyjaśnienie

Na [1::2]końcu jest tylko notacja do wycinania listy. Zwykle ma następującą postać:

some_list[start:stop:step]

Gdybyśmy pominęli start, 0użyto by domyślnej ( ). Zatem pierwszy element (na pozycji 0, ponieważ indeksy są 0oparte na indeksach ) zostałby wybrany. W tym przypadku wybrany zostanie drugi element.

Ponieważ pominięto drugi element, używany jest domyślny (koniec listy). Tak więc lista jest iterowana od drugiego elementu do końca .

Podaliśmy również trzeci argument ( step), którym jest 2. Co oznacza, że ​​jeden element zostanie wybrany, następny zostanie pominięty i tak dalej ...

Podsumowując, w tym przypadku [1::2]oznacza:

  1. weź drugi element (który, nawiasem mówiąc, jest elementem nieparzystym, jeśli sądzisz po indeksie),
  2. pomiń jeden element (ponieważ mamy step=2, więc pomijamy jeden , w przeciwieństwie do tego, step=1który jest domyślny),
  3. weź następny element,
  4. Powtórz kroki 2.-3. aż do końca listy,

EDYCJA : @PreetKukreti podał link do innego wyjaśnienia na temat notacji cięcia list w Pythonie. Zobacz tutaj: Wyjaśnij notację wycinków w Pythonie

Dodatki - zamiana licznika na enumerate()

W swoim kodzie jawnie tworzysz i zwiększasz licznik. W Pythonie nie jest to konieczne, ponieważ możesz wyliczyć kilka iteracyjnych za pomocą enumerate():

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

Powyższe służy dokładnie temu samemu celowi, co kod, którego używałeś:

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

Więcej na temat emulacji forpętli z licznikiem w Pythonie: Dostęp do indeksu w pętlach „for” w Pythonie


@TomWijsman spójrz na to pytanie, aby zrozumieć składnię wycinania Pythona
Preet Kukreti

Pytanie dotyczy dziwnych pozycji. Daje to równe pozycje (0,2,4,6); wygląda na to, że OP chce indeksów (1,3,5), które byłyby podane przez [1,2,3,4,5,6,7][1::2].
Marcin

@Marcin: Tak, właściwie wyszedłem z tego samego wniosku (patrz korekta). To wyszło po dokładnym przeczytaniu kodu OP. Problem wynikał z innej podstawy indeksowania (dla mnie „ nieparzysty ” element oznaczał pierwszy element, dla OP pozornie był drugi , więc indeksowany w 1).
Tadeck,

1
@TomWijsman: Przepraszam, nie zauważyłem, co zmieniłeś. Rzeczywiście, istnieje łącze, ale prowadzi ono do projektu Numarray, a nie do listwycinania Pythona . Trochę się różni, zwłaszcza, że listwycinek nie zachowuje odniesienia do oryginalnej listy (w Numarray musisz jawnie wywołać, .copy()aby mieć coś, co nie odwołuje się do oryginalnej tablicy). Ale miło jest mieć coś, co może być lepsze dla niektórych czytelników. Czy mógłbyś umieścić ten link w komentarzu, abym mógł zagłosować za nim, a pojawi się on tuż pod odpowiedzią?
Tadeck

@Tadeck „Nieparzyste indeksy” całkiem naturalnie oznaczają indeksy, które są liczbami nieparzystymi.
Marcin

12

W przypadku nieparzystych pozycji prawdopodobnie chcesz:

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

3

Lubię listy składane ze względu na ich składnię Math (Set). A co powiesz na to:

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]

Zasadniczo, jeśli wyliczysz na liście, otrzymasz indeks xi wartość y. To, co tutaj robię, to umieszczanie wartości yna liście wyników (parzystych lub nieparzystych) i używanie indeksu, xaby dowiedzieć się, czy ten punkt jest nieparzysty ( x%2 != 0).


1
Czy nie powinno to być wyliczenie (L) zamiast wyliczenia (elementy)?
ab123

0

Możesz użyć operatora bitowego AND &. Zobaczmy poniżej:

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

Operator bitowego AND jest używany z 1, a powód, dla którego działa, ponieważ liczba nieparzysta zapisana w systemie binarnym musi mieć pierwszą cyfrę równą 1. Sprawdźmy

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

Operacja AND z 1 zwróci tylko 1 (1 w systemie binarnym będzie również mieć ostatnią cyfrę 1), jeśli wartość jest nieparzysta.

Więcej informacji znajdziesz na stronie operatora bitowego języka Python .

PS: Możesz użyć tej metody taktycznie, jeśli chcesz wybrać nieparzyste i parzyste kolumny w ramce danych. Powiedzmy, że współrzędne x i y punktów kluczowych twarzy są podane jako kolumny x1, y1, x2 itd ... Aby znormalizować współrzędne xiy z wartościami szerokości i wysokości każdego obrazu, możesz po prostu wykonać

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

Nie jest to dokładnie związane z pytaniem, ale dla naukowców zajmujących się danymi i inżynierów wizji komputerowej ta metoda może być przydatna.

Twoje zdrowie!


-1

list_ = lista (zakres (9)) drukuj (lista_ [1 :: 2])


proszę odpowiedzieć krótkim wyjaśnieniem i umieścić kilka bloków kodu w odpowiednim formacie. Dzięki
venkata krishnan
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.