Python listelerinde neden pop () var ancak push () yok


265

Python'un list.appendişlevinin neden son öğeyi (-1 ile dizinlenmiş olan) kaldıran ve döndüren ve semantik bu kullanımla tutarlı olduğu list.pushgöz önüne alındığında neden çağrılmadığını biliyor mu ?list.poplist.append


21
<nitpick> Bu bir yöntem değil, bir işlev. </nitpick>
Tim Pietzcker

49
Bence bu harika bir soru, ama belki de ifade edilmelidir: "Python listeleri neden pop () var ama push () değil".
Uri

6
poplistenin herhangi bir yerinden öğe çıkarabilir. appendbir şeyi listenin ortasına "itemez".
endolith

@TimPietzcker <nitpick ^ 2> Yöntem gerçekten de bir işlevdir, yöntem (üye işlevi) işlevin bir alt kümesidir :)
jave.web

Yanıtlar:


246

Çünkü "pop" düşünülmeden çok önce "aplike" vardı. Python 0.9.1 destekli liste. 1991 başlarında eklenir. Karşılaştırma olarak, comp.lang.python hakkında 1997'de pop ekleme hakkında bir tartışmanın bir parçası . Guido şunu yazdı:

Bir yığını uygulamak için, bir list.pop () ilkel eklemeniz gerekir (ve hayır, herhangi bir prensip temelinde bu özelliğe karşı değilim). list.push () list.pop () ile simetri için eklenebilir ama aynı işlem için birden fazla ismin büyük bir hayranı değilim - er ya da geç diğerini kullanan kodu okuyacaksınız, bu yüzden ikisini de öğrenmelisiniz, ki bu daha bilişsel bir yüktür.

Ayrıca, push / pop / put / pull öğesinin [0] öğesinde mi yoksa [-1] öğesinden sonra da İkon'un listesine bir başvuru gönderdiği fikrini tartıştığını da görebilirsiniz:

Tüm bunların en iyi liste nesnesi uygulamasının dışında kaldığını düşünüyorum - belirli bir anlam ile bir yığın veya sıraya ihtiyacınız varsa, listeler kullanan küçük bir sınıf yazın

Başka bir deyişle, zaten hızlı append () ve del list [-1] 'i destekleyen doğrudan Python listeleri olarak uygulanan yığınlar için list.pop () öğesinin varsayılan olarak son öğede çalışması mantıklıdır. Diğer diller farklı olsa bile.

Burada örtük olan, çoğu insanın bir listeye eklemesi gerektiğidir, ancak daha az sayıda kişi listeleri yığın olarak ele alma fırsatına sahiptir, bu yüzden list.append çok daha önce geldi.


16
@poige you're going to *read* code that uses the other one (...) which is more cognitive load"İtme yok" u hatırlamak, yalnızca kod yazarken bilişsel yük getirir . Hatırlamak "itme eklemek için tam bir eşanlamlı" olduğunu daha az sıklıkta gördüğünü okuduğunuzda bilişsel yük getirir. Bkz stackoverflow.com/questions/3455488/... insanlar okunabilirliği sıklıkla writeability koz niçin hakkında daha fazla için
stevenjackson121

2
Hiçbir mazeret / anlam yok
poige

15

Çünkü ekler; itmiyor. "Ekleniyor" listenin sonuna ekler, "itmek" öne ekler.

Bir sıraya karşı bir yığın düşünün.

http://docs.python.org/tutorial/datastructures.html

Düzenleme: Benim ikinci cümle daha tam olarak yeniden yazmak için "Ekleme" çok açık bir şekilde temel uygulama ne olursa olsun, bir listenin sonuna bir şey eklemek anlamına gelir . Yeni bir öğenin "itildiğinde" eklendiği yer daha az nettir. Bir yığının üstüne itmek, bir şeyin üstüne "koymak "tır, ancak aslında temeldeki veri yapısına girdiği yer tamamen uygulamaya bağlıdır. Öte yandan, bir kuyruğa itmek, sonuna kadar eklemek anlamına gelir.


4
Eğitici, basitçe sondan itip çıktığını öne sürüyor gibi görünüyor: "Liste yöntemleri, listeyi yığın olarak kullanmayı çok kolaylaştırıyor; burada eklenen son öğe, alınan ilk öğedir (" son giren, ilk çıkan " Yığının en üstüne bir öğe eklemek için append () öğesini kullanın. Yığının en üstünden bir öğe almak için, açık bir dizin olmadan pop () kullanın. "
Uri

110
"itmek" hiçbir şekilde öne eklemek anlamına gelmez. aklı başında bir kişi tarafından yazılan bir yığının her uygulaması yığının alt kısmına (başlangıcına değil) yığının üstüne (sonuna) "iter"
Kip

4
düzeltme: her * dizi tabanlı uygulama. bağlantılı liste uygulaması başa gelecektir.
Kip

16
javascript pushsonuna ekler.
Kobi

2
Hayır, list.popanlambilimi hesaba list.appendkatarak, yığın olarak görüntülendiğinde öğeleri listeye iter.
fortran

10

Listeye bir eleman eklediğinden? İtme genellikle yığınlara atıfta bulunurken kullanılır.


7
Bir liste olsa bir yığın olabilir. :-)
Jason Baker

@JasonBaker Bir listeyi kullanarak bir yığın uygulayabilirsiniz, ancak bu list == stack anlamına gelmez. İsterseniz, bir kuyruğu kuyruk kullanarak da uygulayabilirsiniz. (Bu korkunç derecede verimsiz olurdu, ama mümkün!)
Mark E. Haase

Kafa karışıklığı gerçekten bir yığının bir liste gibi bir "başlangıç" veya "bitiş" değil, daha ziyade bir "üst" ve "alt" olması gerçeğinden kaynaklanmaktadır. Yığına ekleme, öğenin üstüne yerleştirilmesi ve "aşağı itilmesi" anlamına gelir. Önde "itmek" hiçbir anlam ifade etmiyor (en azından dilsel olarak değil). Ve sadece işleri daha da karmaşık hale getirmek için, C ++ "push_front" ve "push_back" kullanır.
JesperE

9

Çünkü "ekle" sezgisel olarak "listenin sonuna ekle" anlamına gelir. "Push" olarak adlandırılmış olsaydı, kuyruğa veya listenin başına bir şeyler ekleyip eklemediğimiz belirsiz olurdu.


12
Bir popoperasyon olduğu için bu bir anlam ifade etmiyor . Yana pushve poptipik yığın işlemleri ve birlikte gidip, bunların listenin aynı sona faaliyet gösterdiklerini beklenmelidir.
jamesdlin

7

Hiçbir şekilde resmi bir cevap değil (sadece dili kullanmaya dayalı bir tahmin), ancak Python listeleri yığın olarak kullanmanıza izin verir (örneğin, öğreticinin 5.1.1 bölümü ). Bununla birlikte, bir liste yine de her şeyden önce bir listedir, bu nedenle her iki işlemde de ortak olan işlemler yığın terimleri (yani push) yerine liste terimlerini (yani, append) kullanır. Pop işlemi listelerde çok yaygın olmadığından ('removeLast' kullanılmış olsa da), pop () tanımladılar, ancak push () tanımlamadılar.


3

Tamam, kişisel görüş burada, ancak Ekle ve Başla bir kümede kesin pozisyonlar anlamına gelir.

Push ve Pop gerçekten bir kümenin her iki ucuna da uygulanabilecek kavramlardır ... Tutarlı olduğunuz sürece ... Bana göre, Push () bir Ayarlamak...


3
Onu getirdiğinden beri, dizilerin bir .append () işlevi varsa, neden karşılık gelen.prepend () işlevi yoktur? Başa eklemek için .insert (0, val) kullanmayı öğrenebilirim, ancak karşılık gelen .delete (pos, val) işlevinin olmaması nedeniyle utanıyorum. ref: docs.python.org/2/library/array.html
MarkHu

3

Bilginize, itme yöntemi olan bir liste yapmak çok zor değil:

>>> class StackList(list):
...     def push(self, item):
...             self.append(item)
... 
>>> x = StackList([1,2,3])
>>> x
[1, 2, 3]
>>> x.push(4)
>>> x
[1, 2, 3, 4]

Bir yığın biraz soyut bir veri tipidir. "İtme" ve "patlatma" fikri yığının gerçekte nasıl uygulandığından büyük ölçüde bağımsızdır. Örneğin, teorik olarak böyle bir yığın uygulayabilirsiniz (neden bilmiyorum):

l = [1,2,3]
l.insert(0, 1)
l.pop(0)

... ve bir yığın uygulamak için bağlantılı listeler kullanmaya başlamamıştım.


1

Push, tanımlanmış bir yığın davranışıdır; (A, B, C, D) yığmak için A'yı (B, C, D) üzerine iterseniz.

Python eki kullandıysanız, elde edilen veri kümesi şöyle görünür (B, C, D, A)

Düzenleme: Vay be, kutsal bilgiçlik.

Örneğimde listenin hangi kısmının en üst, hangi kısmın en alt kısım olduğunu net olarak kabul edeceğim. Buradaki çoğumuzun soldan sağa okuduğunu varsayarsak, herhangi bir listenin ilk öğesi her zaman solda olur.


1
Bu doğru değil, pop listenin sonundan çıkar, önden değil.
fortran

4
bağlantı verdiğiniz sayfayı okuyun. push, yığının üstüne itme olarak tanımlanır. hangi son "üst" uygulama bağlıdır. dizi tabanlı bir yığında itme dizinin sonuna doğru itilir. bağlantılı listeye dayalı bir yığın halinde, push en başa doğru itilir.
Kip

0

Muhtemelen Python'un orijinal sürümü ( C Python) C ++ ile değil C ile yazılmıştı.

Bir şeyin bir şeyin arkasına itilmesiyle oluşturulduğu fikri, muhtemelen onları ekleme düşüncesi kadar iyi bilinmemektedir.


İkinci bölüm iyi bir cevap. Fakat bunun C / C ++ 'da uygulanmasıyla ne ilgisi var?
Jason Baker

@Jason: C ++ 'ın STL'sinde push_back () listeye nasıl eklenir. Listelerin iterek oluşturulduğu fikrinin belki de C ++ 'da çalışıyorsanız ortaya çıkma olasılığı daha yüksek olduğu meta-fikrini aktarmaya çalışıyordum. Bir anlam ifade ediyor musun?
gevşeyin

Bitişik bir dizi (C ++ 'da bir vektör, Python'da bir liste, Perl'de bir dizi) olarak uygulanan bir liste türünüz varsa, yeni öğeyi sonuna "itmek" in mantıklı olması mantıklıdır. Perl 4'ün, Python'un append / pop ve C ++ 's push_back / pop_back gibi dizilerde fonksiyon olarak "push" ve "pop" varsaydığını ve STL'nin C ++' a resmen önerilmesinden çok önce olduğunu lütfen unutmayın. Bu yüzden, C ++ 'ın STL'si ile yeni bir anlayış yaratan hiçbir ilgisi yok.
Andrew Dalke

Python'u Perl arka planından öğrenmeyi özlediğim şeylerden biri, aynı ucun her iki ucuna öğe eklemek / kaldırmak için yerleşik push (), pop (), shift () ve unshift () işlemlerini kullanma yeteneğidir. dizi . Bir Python listesini bir "Stackish" sınıfına ya da "Queueish" sınıfına kolayca satabilmeme rağmen, her ikisini birden yapmak o kadar kolay (ya da verimli) görünmüyor.
Peter

-2

İtme ve Pop, bir kafeterya veya büfe içindeki bir tabak veya tepsi yığınının, özellikle alt plakanın altında bir yayı olan tutucu tipinde olanların (az ya da çok ... teoride) metaforu açısından anlamlıdır. altında ne kadar plaka olursa olsun aynı yerde.

Bir tepsiyi çıkarırsanız, yay üzerindeki ağırlık biraz daha azdır ve istif biraz "açılır", plakayı geri koyarsanız, istifi "iter". Listeyi bir yığın ve son unsuru üstte olarak düşünürseniz, o zaman çok fazla karışıklık yaşamamalısınız.

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.