2012-08-31 19 views
39

Czy istnieje sposób na pocięcie tylko pierwszego i ostatniego elementu na liście?Pierwszy i ostatni element w Pythonie na liście

Na przykład; Jeśli jest to moja lista:

>>> some_list 
['1', 'B', '3', 'D', '5', 'F'] 

Chcę to zrobić (oczywiście [0,-1] nie jest prawidłowa składnia):

>>> first_item, last_item = some_list[0,-1] 
>>> print first_item 
'1' 
>>> print last_item 
'F' 

Niektóre rzeczy próbowałem:

In [3]: some_list[::-1] 
Out[3]: ['F', '5', 'D', '3', 'B', '1'] 

In [4]: some_list[-1:1:-1] 
Out[4]: ['F', '5', 'D', '3'] 

In [5]: some_list[0:-1:-1] 
Out[5]: [] 
... 
+5

Haha 3 odpowiedzi, identycznych, na przestrzeni 2 sekundy, a jeden był twój. Klasyczny. – Aesthete

+3

Co jest złego w przypadku 'first, last = some_list [0], some_list [-1]'? –

+0

@MatthewAdams Ponieważ dzielę go na tę samą linię i musiałbym poświęcić czas na podzielenie go dwukrotnie: 'x, y = a.split (" - ") [0], a.split (" - ") [ -1] '. – chown

Odpowiedz

60

Jednym ze sposobów:

some_list[::len(some_list)-1] 

Lepszym sposobem (nie używa krojenie, ale jest łatwiejsze do odczytania):

[some_list[0], some_list[-1]] 
+14

Druga forma jest * dużo * bardziej czytelna. Jawny jest lepszy niż niejawny. –

+3

Stąd "prawdopodobnie lepszy sposób". jedynym powodem, dla którego nie powiedziałem tego po raz pierwszy, jest to, że pytanie jednoznacznie prosi o "plasterek", a druga forma nie jest technicznie kawałkiem ... – mgilson

+2

Nigdy nie jest za późno, by uświadomić OP o głupocie jego dróg. :-P –

6

You można to zrobić tak:

some_list[0::len(some_list)-1] 
3

Właściwie tylko zorientowaliśmy się:

In [20]: some_list[::len(some_list) - 1] 
Out[20]: ['1', 'F'] 
5

Co z tym?

>>> first_element, last_element = some_list[0], some_list[-1] 
11

Pomyślałem, że pokażę jak to zrobić ozdobnego indeksowania NumPy za:

>>> import numpy 
>>> some_list = ['1', 'B', '3', 'D', '5', 'F'] 
>>> numpy.array(some_list)[[0,-1]] 
array(['1', 'F'], 
     dtype='|S1') 

pamiętać, że również obsługuje dowolne lokalizacje indeksu, którego metoda [::len(some_list)-1] nie będzie pracować dla:

>>> numpy.array(some_list)[[0,2,-1]] 
array(['1', '3', 'F'], 
     dtype='|S1') 

Jak wskazuje DSM, można zrobić coś podobnego z itemgetter:

>>> import operator 
>>> operator.itemgetter(0, 2, -1)(some_list) 
('1', '3', 'F') 
+2

Numpy jest po prostu zbyt niesamowita ... – mgilson

+0

numpy zwykle sprawia, że ​​się uśmiecham! – jterrace

+3

Możesz uzyskać wariant tego do pracy używając 'itemgetter' bez' numpy': 'itemgetter (0, -1) (some_list)'. – DSM

4

Wygląda na to, że niektórzy ludzie odpowiadają na niewłaściwe pytanie. Mówiłeś, że chcesz to zrobić.

>>> first_item, last_item = some_list[0,-1] 
>>> print first_item 
'1' 
>>> print last_item 
'F' 

Czyli chcesz wyodrębnić pierwsze i ostatnie elementy każdego na oddzielne zmiennych.

W tym przypadku odpowiedzi udzielone przez Matthew Adams, pemistahl i katrielalex są ważne. Jest to po prostu przypisanie związek:

first_item, last_item = some_list[0], some_list[-1] 

Ale później stwierdzić powikłanie: „Jestem dzieląc go w tej samej linii, i że będzie musiał spędzić czas dzieląc go dwukrotnie:”

x, y = a.split("-")[0], a.split("-")[-1] 

Aby więc uniknąć dwóch wywołań split(), musisz operować tylko na liście, która jest wynikiem podziału na jeden raz.

W tym przypadku próba wykonania zbyt dużej liczby wierszy jest szkodliwa dla przejrzystości i prostoty.Użyć zmiennej trzymać podziału wynik: „Jak dostać nową listę, składającą się z pierwszych i ostatnich elementów listy”

lst = a.split("-") 
first_item, last_item = lst[0], lst[-1] 

Inne odpowiedzi udzielić odpowiedzi na pytanie, Prawdopodobnie zainspirował ich twój tytuł, który wymienia krojenie, którego tak naprawdę nie chcesz, zgodnie z uważną lekturą twojego pytania.

AFAIK są 3 sposoby, aby zdobyć nową listę z 0TH i ostatnich elementów listy:

>>> s = 'Python ver. 3.4' 
>>> a = s.split() 
>>> a 
['Python', 'ver.', '3.4'] 

>>> [ a[0], a[-1] ]  # mentioned above 
['Python', '3.4'] 

>>> a[::len(a)-1]   # also mentioned above 
['Python', '3.4'] 

>>> [ a[e] for e in (0,-1) ] # list comprehension, nobody mentioned? 
['Python', '3.4'] 

# Or, if you insist on doing it in one line: 
>>> [ s.split()[e] for e in (0,-1) ] 
['Python', '3.4'] 

Zaletą podejścia lista ze zrozumieniem, jest to, że zestaw wskaźników w krotce może być dowolna i generowane programowo.

1

Można użyć coś takiego `

y[::max(1, len(y)-1)] 

jeśli naprawdę chcesz używać krojenia. Zaletą tego jest to, że nie może podawać błędów indeksowania i działa również z listami długości 1 lub 0.

0

To nie jest "plaster", ale jest to ogólne rozwiązanie, które nie korzysta z jawnego indeksowania i działa w scenariuszu, w którym dana sekwencja jest anonimowa (dzięki czemu można tworzyć i "wycinać" na sama linia, nie tworząc dwa razy i dwa razy indeksowania): operator.itemgetter

import operator 

# Done once and reused 
first_and_last = operator.itemgetter(0, -1) 

... 

first, last = first_and_last(some_list) 

można po prostu go jako inline (po from operator import itemgetter dla zwięzłości w czasie użycia):

first, last = itemgetter(0, -1)(some_list) 

ale jeśli będziesz ponowne dużo gettera, możesz zapisać pracę odtwarzania (np d nadać mu użyteczną, samo-dokumentującą nazwę), tworząc ją raz z góry.

Zatem dla konkretnego przypadku użycia, można wymienić:

x, y = a.split("-")[0], a.split("-")[-1] 

z:

x, y = itemgetter(0, -1)(a.split("-")) 

i split tylko raz bez zapisywania kompletny list w trwałym nazwy dla len kontroli lub podwójne -indeksowanie lub podobne.

Zauważ, że itemgetter dla wielu elementów zwraca tuple, a nie list, więc jeśli nie jesteś tylko rozpakowanie go do konkretnych nazwisk, i potrzebują prawdziwego list, trzeba zawinąć wywołanie w konstruktorze list.

0

Python 3 tylko odpowiedzieć (który nie używa krojenia lub wyrzucić resztę list, ale może być wystarczająco dobre, w każdym razie) jest użycie rozpakowaniu uogólnienia dostać first i last odrębny od środka:

first, *_, last = some_list 

Wybór _ jako catchall dla "odpoczynku" argumentów jest arbitralny; będą przechowywane pod nazwą _, która jest często używana jako stand-in dla "rzeczy, których nie obchodzi".

W przeciwieństwie do wielu innych rozwiązań, ten zapewnia, że ​​są co najmniej dwa elementy w sekwencji; jeśli jest tylko jeden (więc first i last byłyby identyczne), spowoduje to zgłoszenie wyjątku (ValueError).

0

Case bardziej ogólnym: Powrót N punktów od każdego końca listy

Odpowiedzi pracować specyficzny pierwszy i ostatni, ale niektóre, jak ja, może szukasz rozwiązania, które mogą być stosowane wobec bardziej ogólny przypadek, w którym można powrócić z najlepszymi N punktów z obu stron na liście (powiedzmy masz listę posortowaną i tylko chcesz 5 najwyższy lub najniższy), wymyśliłem następujące rozwiązanie:

In [1] 
def GetWings(inlist,winglen): 
    if len(inlist)<=winglen*2: 
     outlist=inlist 
    else: 
     outlist=list(inlist[:winglen]) 
     outlist.extend(list(inlist[-winglen:])) 
    return outlist 

oraz przykład powrotu najniższych i najwyższych 3 liczb z listy 1-10:

In [2] 
GetWings([1,2,3,4,5,6,7,8,9,10],3) 

#Out[2] 
#[1, 2, 3, 8, 9, 10] 
-2
def recall(x): 
    num1 = x[-4:] 
    num2 = x[::-1] 
    num3 = num2[-4:] 
    num4 = [num3, num1] 
    return num4 

Teraz wystarczy zrobić zmiennej poza funkcją i przywołać funkcję: tak:

avg = recall("idreesjaneqand") 
print(avg) 
Powiązane problemy