Bir listenin son öğesini alma


Yanıtlar:


3107

some_list[-1] en kısa ve en Pitoniktir.

Aslında, bu sözdizimi ile çok daha fazlasını yapabilirsiniz. some_list[-n]Sözdizimi nth-to-son öğe alır. Böylece some_list[-1]son elementi some_list[-2]alır, ikincisini alır, vb. Sonuna kadar alır some_list[-len(some_list)], bu da size ilk elementi verir.

Liste öğelerini de bu şekilde ayarlayabilirsiniz. Örneğin:

>>> some_list = [1, 2, 3]
>>> some_list[-1] = 5 # Set the last element
>>> some_list[-2] = 3 # Set the second to last element
>>> some_list
[1, 3, 5]

Bir liste öğesini dizine göre almanın IndexError, beklenen öğe yoksa bir artıracağını unutmayın. Bu , boş bir listenin son bir öğeye sahip olamayacağı some_list[-1]için bir istisna doğuracağı anlamına gelir some_list.


6
Gibi bir şey özledim some_list.last- güzel bir kod satırı olurdu
Dmitry P.

257

Sizin str()veya list()nesneleriniz bu şekilde boş kalabilirse: astr = ''veya alist = [], "eşlik" nesnesi alist[-1:]yerine kullanmak isteyebilirsiniz alist[-1].

Bunun önemi:

alist = []
alist[-1]   # will generate an IndexError exception whereas 
alist[-1:]  # will return an empty list
astr = ''
astr[-1]    # will generate an IndexError exception whereas
astr[-1:]   # will return an empty str

Burada yapılan ayrım, boş liste nesnesinin veya boş str nesnesinin döndürülmesinin, bir istisna nesnesinden çok "son öğe" olduğu şeklindedir.


26
Bu cevabın özünün yanlış olduğunu düşündüğüm için indirildi. Bir öğeyi istediğinizde bir liste almak, yalnızca kaçınılmaz "liste dizinini aralık dışında" erteler - ve boş bir listeden bir öğe almaya çalışırken bu olması gerekir. Dizeler için astr [-1:] geçerli bir yaklaşım olabilir çünkü astr [-1] ile aynı türü döndürür, ancak ':' boş listelerle başa çıkmaya yardımcı olduğunu düşünmüyorum (ve soru listelerle ilgili) . Eğer fikir "len (alist)> 0" yerine koşullu olarak "alist [-1:]" kullanmaksa, daha sonra kullanmak daha kolay okunabilir. (bir şeyi kaçırırsam oy kullanmaktan mutluluk duyarız)
Stan Kurdziel

9
Aşağı oyunuz anlaşılabilir ve geçerlidir. Ancak, istisna nesnelerinin amaçlandığı iki temel kamp olduğunu düşünüyorum. Bir kesinlik, istisnaların uygulamanızı durdurmasıdır. Kamplardan biri deneme yan tümcelerinde istisnalar kullanır, diğer kamp bunun yerine if len (alist)> 0: yapısını kullanır. Her durumda, istisnalar kodunuzu durduran nesnelerdir. Ve benim gibi kod daha sonra durmaz "null" - sıraları gibi daha az dizi nesnesi vardır. Benim tercihim, bir try yan tümcesi ile önceden kodumu durduran nesneler yerine "null" nesneleri sınamak için IF yan tümcelerini kullanmaktır.
DevPlayer

6
Dilim sözdizimi tartışmaya değer olduğu için seçildi, ancak @StanKurdziel ile morfolojinin yanlış olduğunu kabul ediyorum, sadece goalpost'u hareket ettiriyorsunuz - kendi çözümümün birincil kullanımıyla ilgili olduğunu buldum ' 'zaten eklemeyin' (delta çizgi grafikleri), böylece birleştirilmiş ifade if len(my_vector) == 0 or my_vector[-1] != update_valuygulanabilir bir kalıptır. ama kesinlikle küresel bir çözüm değil - hiçbiri sonuç alınamayan bir sözdizimi formuna sahip olmak güzel olurdu
Mark Mullin

17
xs[-1] if xs else None
Gabriel

2
Neden bir IndexError'dan "kaçınmalısınız"? Boş bir listeyi veya dizeyi dizine eklemeye çalışırsanız bir istisna alırsınız. Bu istisnayı ele almak istiyorsanız, bir dene / hariç kullan - bunun için var.
Chris Johnson

94

Ayrıca şunları da yapabilirsiniz:

alist.pop()

Bu, listenizle ne yapmak istediğinize bağlıdır, çünkü pop()yöntem son öğeyi siler.


71

Python'da son öğeyi görüntülemenin en basit yolu

>>> list[-1:] # returns indexed value
    [3]
>>> list[-1]  # returns value
    3

böyle bir hedefe ulaşmak için başka birçok yöntem vardır, ancak bunlar kısa ve tatlıdır.


2
Liste uzunluğunuz sıfırsa, bu çözüm list[-1]hata verirken çalışır .
anon01

Ne? Bunu neden yaptın a[-1:][0] hiç ? Yine de sağlar a[-1]. Açıklama lütfen?
kaboom

52

Python'da bir listenin son öğesini nasıl elde edersiniz?

Sadece son elementi elde etmek için,

  • listeyi değiştirmeden ve
  • Eğer liste biliyorum varsayarak olan bir son öğe (yani o nonempty olan)

-1alt simge gösterimine geçmek :

>>> a_list = ['zero', 'one', 'two', 'three']
>>> a_list[-1]
'three'

açıklama

Dizinler ve dilimler bağımsız değişken olarak negatif tamsayıları alabilir.

Belgelerde bir örnek her dizinin hangi dizide başvurduğunu göstermek için değiştirdim, bu durumda, dize "Python", -1son öğe, karakter, başvuruyor 'n':

 +---+---+---+---+---+---+
 | P | y | t | h | o | n |
 +---+---+---+---+---+---+
   0   1   2   3   4   5 
  -6  -5  -4  -3  -2  -1

>>> p = 'Python'
>>> p[-1]
'n'

Tekrarlanabilir ambalajdan çıkarma ile atama

Bu yöntem, yalnızca son öğeyi elde etmek amacıyla değil, tamlık uğruna (ve sadece listeleri değil - tüm yinelenebilirleri desteklediğinden) gereksiz yere ikinci bir liste gerçekleştirebilir:

>>> *head, last = a_list
>>> last
'three'

Değişken adı, kafa gereksiz yeni oluşturulan listeye bağlanır:

>>> head
['zero', 'one', 'two']

Bu listeyle hiçbir şey yapmak istemezseniz, bu daha uygun olur:

*_, last = a_list

Veya, bunun bir liste olduğunu biliyorsanız (veya en azından alt simge gösterimini kabul ediyorsanız):

last = a_list[-1]

Bir işlevde

Bir yorumcu şunları söyledi:

Keşke Python, Lisp'in yaptığı gibi ilk () ve son () için bir fonksiyona sahip olsaydı ... gereksiz lambda fonksiyonlarından çok kurtulacaktı.

Bunları tanımlamak oldukça basit olacaktır:

def last(a_list):
    return a_list[-1]

def first(a_list):
    return a_list[0]

Veya şunu kullanın operator.itemgetter:

>>> import operator
>>> last = operator.itemgetter(-1)
>>> first = operator.itemgetter(0)

Her iki durumda da:

>>> last(a_list)
'three'
>>> first(a_list)
'zero'

Özel durumlar

Daha karmaşık bir şey yapıyorsanız, son öğeyi biraz farklı şekillerde almanın daha performanslı olduğunu görebilirsiniz.

Programlama konusunda yeniyseniz, bu bölümden kaçınmalısınız, çünkü algoritmaların anlamsal olarak farklı kısımlarını bir araya getirir. Algoritmanızı bir yerde değiştirirseniz, başka bir kod satırı üzerinde istenmeyen bir etkisi olabilir.

Uyarılar ve koşulları olabildiğince tamamen sağlamaya çalışıyorum, ama bir şeyleri kaçırmış olabilirim. Eğer bir uyarı bıraktığımı düşünüyorsanız lütfen yorum yapın.

Dilimleme

Listenin bir dilimi yeni bir liste döndürür - böylece öğeyi yeni bir listede isteyeceksek -1'den sonuna kadar dilimleyebiliriz:

>>> a_slice = a_list[-1:]
>>> a_slice
['three']

Liste boşsa, bunun başarısız olmaması da tersidir:

>>> empty_list = []
>>> tail = empty_list[-1:]
>>> if tail:
...     do_something(tail)

Endeksle erişmeye çalışmak, IndexErrorbununla ilgilenilmesi gereken bir artış sağlar:

>>> empty_list[-1]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

Fakat yine de, bu amaç için dilimleme sadece ihtiyacınız varsa yapılmalıdır:

  • yeni bir liste oluşturuldu
  • ve önceki liste boşsa yeni liste boş olur.

for döngüler

Python'un bir özelliği olarak, bir fordöngüde iç kapsam belirleme yoktur .

Liste üzerinde zaten tam bir yineleme yapıyorsanız, son öğeye yine de döngüde atanan değişken adı başvurur:

>>> def do_something(arg): pass
>>> for item in a_list:
...     do_something(item)
...     
>>> item
'three'

Bu semantik olarak listedeki son şey değildir. Bu, anlamsal olarak, adın itembağlı olduğu son şeydir .

>>> def do_something(arg): raise Exception
>>> for item in a_list:
...     do_something(item)
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "<stdin>", line 1, in do_something
Exception
>>> item
'zero'

Bu nedenle, yalnızca son öğeyi almak için kullanılmalıdır.

  • zaten dönüyorlar ve
  • Döngünün biteceğini (hatalar nedeniyle kesilmeyeceğini veya çıkmayacağını) biliyorsunuz, aksi takdirde döngü tarafından başvurulan son öğeye işaret edecektir.

Alma ve kaldırma

Ayrıca, son öğeyi kaldırarak ve geri göndererek orijinal listemizi değiştirebiliriz:

>>> a_list.pop(-1)
'three'
>>> a_list
['zero', 'one', 'two']

Ancak şimdi orijinal liste değiştirildi.

( -1aslında varsayılan bağımsız değişkendir, bu nedenle list.popdizin bağımsız değişkeni olmadan kullanılabilir):

>>> a_list.pop()
'two'

Bunu yalnızca

  • listenin içinde öğeler olduğunu biliyor veya boşsa istisnayı ele almaya hazırsınız ve
  • son öğeyi bir yığın gibi davranarak listeden kaldırmayı planlıyorsunuz.

Bunlar geçerli kullanım durumlarıdır, ancak çok yaygın değildir.

Geri kalanını daha sonra kullanmak üzere kaydetmek:

Neden bunu yapacağınızı bilmiyorum, ancak tamlık için, reversedbir yineleyici döndürdüğü için (yineleyici protokolünü destekler) sonucunu aktarabilirsiniz next:

>>> next(reversed([1,2,3]))
3

Yani bunun tersini yapmak gibi:

>>> next(iter([1,2,3]))
1

Ama daha sonra ters yineleyicinin geri kalanına ihtiyacınız olmayacaksa, bunu yapmak için iyi bir neden düşünemiyorum, ki bu muhtemelen daha fazla görünecektir:

reverse_iterator = reversed([1,2,3])
last_element = next(reverse_iterator)

use_later = list(reverse_iterator)

ve şimdi:

>>> use_later
[2, 1]
>>> last_element
3

14

Önlemek IndexError: list index out of rangeiçin bu sözdizimini kullanın:

mylist = [1, 2, 3, 4]

# With None as default value:
value = mylist and mylist[-1]

# With specified default value (option 1):
value = mylist and mylist[-1] or 'default'

# With specified default value (option 2):
value = mylist[-1] if mylist else 'default'


10

lst[-1]en iyi yaklaşımdır, ancak genel yinelemelerle şunları göz önünde bulundurun more_itertools.last:

kod

import more_itertools as mit


mit.last([0, 1, 2, 3])
# 3

mit.last(iter([1, 2, 3]))
# 3

mit.last([], "some default")
# 'some default'

6

list[-1]listeyi değiştirmeden listenin son öğesini alır. list.pop()listenin son öğesini alır, ancak orijinal listeyi değiştirir / değiştirir. Genellikle, orijinal listenin değiştirilmesi önerilmez.

Alternatif olarak, herhangi bir nedenle, list[len(list)-1]listenin boş olmadığı varsayılarak daha az pitonik bir şey arıyorsanız kullanabilirsiniz .


2
Orijinal listeyi değiştirmenin genellikle tavsiye edilmediğini varsaymak muhtemelen kötüdür, çünkü sonuçta çok yaygın olarak gerçekleştirilir
Aaron

6

Liste boşken IndexError almak istemiyorsanız aşağıdaki kodu da kullanabilirsiniz.

next(reversed(some_list), None)

4

Tamam, ama hemen hemen her dilde ortak olan ne items[len(items) - 1]? Bu, IMO'dur, son öğeyi almanın en kolay yolu, çünkü hiçbir şey pitonik bilgi gerektirmez .


3
items [len (items) - 1] esasen Python'un kaputun altında yaptığı şeydir, ancak bir dizinin len dizisinde zaten depolandığından saymaya gerek yoktur, gereğinden fazla iş yaratırsınız.
Dan Gayle

21
Python yazdığınız için, gerçekten daha Pythonic olmaya çalışmalısınız
Michael Wu

5
@MichaelWu Bunu yapmanın bir anlamı yok. Pythonic yolu genellikle açıklayıcı değildir, projeye yeni kişileri tanıtmanız gerektiğinde daha fazla dikkat gerektirir ve elbette Java gibi diğer dillere geçmeniz gerektiğinde işe yaramaz - Python'a özgü bilgileri kullanamazsınız. Mümkün olduğunca pythonic yolu atladığınızda, aylar / yıllar sonra projeye geri dönmek de çok daha kolaydır.
Radek Anuszewski

7
@Pneumokok Dikkat çekiyorsunuz, ancak liste indekslemenin jeneratörlere kıyasla çok temel bir Python tekniği . Ayrıca, tek tek dil araçlarından ve sözdiziminden yararlanmayacaksanız neden C veya belki javascript dışında bir şey kullanmaya zahmet ediyorsunuz? O zaman tüm projelerinizde her şeyi sürekli zor bir şekilde yapabilirsiniz.
Matthew Purdon

Çok pitonik olmasa da, bunun bazı açılardan daha iyi olduğunu düşünüyorum. some_list[-1] yaklaşımdan çünkü daha mantıklı ve aslında some_list[-1]bence daha iyi ne yaptığını gösteriyor .
Byron Filer
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.