Mengapa daftar python memiliki pop () tetapi tidak mendorong ()

265

Adakah yang tahu mengapa list.appendfungsi Python tidak dipanggil list.pushmengingat sudah ada list.popyang menghapus dan mengembalikan elemen terakhir (yang diindeks pada -1) dan list.appendsemantik konsisten dengan penggunaan itu?

Eddie Welker
sumber
21
<nitpick> Ini metode, bukan fungsi. </nitpick>
Tim Pietzcker
49
Saya pikir ini adalah pertanyaan yang bagus, meskipun mungkin harus diutarakan: "Mengapa daftar python memiliki pop () tetapi tidak mendorong ()".
Uri
6
popdapat mengeluarkan item dari mana saja dalam daftar. appendtidak dapat "mendorong" sesuatu ke tengah daftar.
endolith
@TimPietzcker <nitpick ^ 2> Metode, memang, juga fungsi, metode (fungsi anggota) adalah bagian dari fungsi :)
jave.web

Jawaban:

246

Karena "append" sudah ada jauh sebelum "pop" dipikirkan. Python 0.9.1 mendukung list.append pada awal 1991. Sebagai perbandingan, inilah bagian dari diskusi tentang comp.lang.python tentang menambahkan pop pada tahun 1997. Guido menulis:

Untuk mengimplementasikan stack, seseorang perlu menambahkan list.pop () primitif (dan tidak, saya tidak menentang yang khusus ini berdasarkan prinsip apa pun). list.push () dapat ditambahkan untuk simetri dengan list.pop () tapi saya bukan penggemar banyak nama untuk operasi yang sama - cepat atau lambat Anda akan membaca kode yang menggunakan yang lain, jadi Anda perlu mempelajari keduanya, yang merupakan beban kognitif lebih.

Anda juga dapat melihat dia membahas ide apakah push / pop / put / pull harus di elemen [0] atau setelah elemen [-1] di mana ia memposting referensi ke daftar Ikon:

Saya masih berpikir bahwa semua ini sebaiknya ditinggalkan dari implementasi objek daftar - jika Anda memerlukan stack, atau antrian, dengan semantik tertentu, tulis kelas kecil yang menggunakan daftar

Dengan kata lain, untuk tumpukan diimplementasikan secara langsung sebagai daftar Python, yang sudah mendukung append cepat (), dan daftar del [-1], masuk akal bahwa list.pop () bekerja secara default pada elemen terakhir. Bahkan jika bahasa lain melakukannya secara berbeda.

Tersirat di sini adalah bahwa kebanyakan orang perlu menambahkan ke daftar, tetapi lebih sedikit memiliki kesempatan untuk memperlakukan daftar sebagai tumpukan, itulah sebabnya list.append datang jauh lebih awal.

Andrew Dalke
sumber
16
@poige you're going to *read* code that uses the other one (...) which is more cognitive loadMengingat "tidak ada dorongan" hanya memperkenalkan beban kognitif saat Anda menulis kode. Mengingat "push adalah sinonim yang tepat untuk menambahkan" memperkenalkan muatan kognitif setiap kali Anda membaca yang Anda lihat lebih jarang digunakan. Lihat stackoverflow.com/questions/3455488/… untuk lebih lanjut tentang mengapa orang berpikir keterbacaan seringkali mengalahkan kemampuan menulis
stevenjackson121
2
Tidak ada alasan / akal
poige
15

Karena itu menambahkan; itu tidak mendorong. "Menambahkan" menambah di akhir daftar, "mendorong" menambahkan ke depan.

Pikirkan antrian vs. tumpukan.

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

Sunting: Untuk menulis ulang kalimat kedua saya dengan lebih tepat, "Menambahkan" dengan sangat jelas menyiratkan menambahkan sesuatu ke akhir daftar, terlepas dari implementasi yang mendasarinya. Di mana elemen baru ditambahkan ketika "didorong" kurang jelas. Mendorong ke tumpukan adalah meletakkan sesuatu di "atas," tetapi di mana ia sebenarnya berada dalam struktur data yang mendasarinya sepenuhnya tergantung pada implementasi. Di sisi lain, mendorong ke antrian berarti menambahkannya ke akhir.

Matt Ball
sumber
4
Tutorial tampaknya menyarankan bahwa itu hanya mendorong dan muncul dari akhir: "Metode daftar membuatnya sangat mudah untuk menggunakan daftar sebagai tumpukan, di mana elemen terakhir yang ditambahkan adalah elemen pertama yang diambil (" last-in, first-out "). Untuk menambahkan item ke atas tumpukan, gunakan append (). Untuk mengambil item dari atas tumpukan, gunakan pop () tanpa indeks eksplisit."
Uri
110
"mendorong" sama sekali tidak berarti menambahkan ke depan. setiap implementasi tumpukan yang pernah ditulis oleh orang waras "mendorong" ke atas (ujung) tumpukan, bukan bagian bawah (mulai) tumpukan
Kip
4
koreksi: setiap implementasi berbasis * array . implementasi daftar-tertaut akan mendorong ke kepala.
Kip
16
javascript pushmenambah sampai akhir.
Kobi
2
Tidak, setelah masuk ke dalam list.popsemantik akun , list.appendmendorong elemen ke dalam daftar, bila dilihat sebagai tumpukan.
fortran
10

Karena itu menambahkan elemen ke daftar? Push biasanya digunakan ketika mengacu pada tumpukan.

JesperE
sumber
7
Daftar bisa berupa tumpukan. :-)
Jason Baker
@JasonBaker Anda dapat menerapkan tumpukan menggunakan daftar, tetapi itu tidak berarti daftar == tumpukan. Anda juga bisa menerapkan tumpukan menggunakan antrian, jika Anda benar-benar menginginkannya. (Akan sangat tidak efisien, tetapi itu mungkin!)
Mark E. Haase
Kebingungan benar-benar berasal dari kenyataan bahwa tumpukan tidak memiliki "awal" atau "akhir" seperti daftar, tetapi lebih sebagai "atas" dan "bawah". Menambahkan ke tumpukan menyiratkan menempatkan elemen di atas dan "mendorong" ke bawah. "Mendorong" di depan tidak masuk akal (setidaknya tidak secara linguistik). Dan hanya untuk membuat hal-hal semakin membingungkan, C ++ menggunakan "push_front" dan "push_back".
JesperE
9

Karena "tambahkan" secara intuitif berarti "tambahkan di akhir daftar". Jika itu disebut "push", maka tidak akan jelas apakah kita menambahkan barang di bagian ekor atau di bagian atas daftar.

Gyom
sumber
12
Ini tidak masuk akal karena ada popoperasi. Karena pushdan popbiasanya menumpuk operasi dan berjalan bersama, harus diharapkan bahwa mereka beroperasi di ujung daftar yang sama.
jamesdlin
7

Bukan jawaban resmi dengan cara apa pun (hanya tebakan berdasarkan penggunaan bahasa), tetapi Python memungkinkan Anda menggunakan daftar sebagai tumpukan (misalnya, bagian 5.1.1 dari tutorial ). Namun, daftar masih merupakan yang pertama dari semua daftar, sehingga operasi yang umum untuk keduanya menggunakan istilah daftar (yaitu, tambahkan) daripada istilah tumpukan (yaitu, push). Karena operasi pop tidak biasa dalam daftar (meskipun 'removeLast' bisa digunakan), mereka mendefinisikan pop () tetapi bukan push ().

Uri
sumber
3

Ok, pendapat pribadi di sini, tetapi Tambahkan dan Taruh menyiratkan posisi yang tepat dalam satu set.

Push dan Pop benar-benar konsep yang dapat diterapkan pada kedua ujung set ... Asalkan Anda konsisten ... Untuk beberapa alasan, bagi saya, Push () sepertinya harus diterapkan ke bagian depan perangkat set...

dicroce
sumber
3
Karena Anda memunculkannya, jika array memiliki fungsi .append (), lalu mengapa tidak ada fungsi korespondensi.prepend ()? Saya bisa belajar menggunakan .insert (0, val) untuk menambahkan, tetapi saya malu dengan kurangnya fungsi .delete (pos, val) yang sesuai. ref: docs.python.org/2/library/array.html
MarkHu
3

FYI, tidak terlalu sulit untuk membuat daftar yang memiliki metode push:

>>> 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]

Tumpukan adalah tipe data yang agak abstrak. Gagasan "mendorong" dan "meletus" sebagian besar tidak tergantung pada bagaimana stack sebenarnya diimplementasikan. Misalnya, Anda secara teoritis dapat mengimplementasikan tumpukan seperti ini (walaupun saya tidak tahu mengapa Anda mau):

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

... dan saya belum menggunakan daftar tertaut untuk mengimplementasikan tumpukan.

Jason Baker
sumber
1

Push adalah perilaku stack yang didefinisikan ; jika Anda mendorong A ke tumpukan (B, C, D) Anda akan mendapatkan (A, B, C, D).

Jika Anda menggunakan python append, dataset yang dihasilkan akan terlihat seperti (B, C, D, A)

Sunting: Wow, kesedihan suci.

Saya akan berasumsi bahwa akan menjadi jelas dari contoh saya bagian mana dari daftar yang paling atas, dan bagian mana yang paling bawah. Dengan asumsi bahwa sebagian besar dari kita di sini membaca dari kiri ke kanan, elemen pertama dari daftar mana pun selalu berada di sebelah kiri.

Satanicpuppy
sumber
1
Itu tidak benar, pop menghapus dari akhir daftar, bukan dari depan.
fortran
4
baca halaman yang Anda tautkan. push didefinisikan sebagai mendorong ke atas tumpukan. yang ujungnya "atas" tergantung pada implementasi. dalam tumpukan berbasis array, push akan mendorong ke ujung array. dalam tumpukan berbasis daftar tertaut, push akan mendorong ke awal.
Kip
0

Mungkin karena versi asli Python ( C Python) ditulis dalam C, bukan C ++.

Gagasan bahwa daftar dibentuk dengan mendorong sesuatu ke belakang sesuatu mungkin tidak seterkenal pemikiran menambahkannya.

beristirahat
sumber
Bagian kedua adalah jawaban yang bagus. Tapi apa hubungannya dengan penerapan C / C ++?
Jason Baker
@Jason: Di STLL C ++, push_back () adalah cara Anda menambahkan ke daftar. Saya mencoba menyampaikan meta-ide bahwa gagasan bahwa daftar dibentuk dengan mendorong mungkin lebih mungkin muncul jika Anda bekerja di C ++. Masuk akal?
bersantai
Jika Anda memiliki tipe daftar diimplementasikan sebagai array yang berdekatan (vektor dalam C ++, daftar dengan Python, array di Perl) maka masuk akal untuk memiliki "push" menempatkan elemen baru di akhir. Anda akan perhatikan bahwa perl 4 seharusnya "push" dan "pop" sebagai fungsi pada array persis seperti append / pop Python dan push_back / pop_back C ++, dan jauh sebelum STL secara resmi diusulkan ke C ++. Jadi itu tidak ada hubungannya dengan STLL C ++ menciptakan pemahaman baru tentang berbagai hal.
Andrew Dalke
Salah satu hal yang saya lewatkan belajar Python dari latar belakang Perl adalah kemampuan untuk menggunakan built-in push (), pop (), shift (), dan operasi unshift () untuk menambah / menghapus elemen ke / dari kedua ujung yang sama Array . Meskipun saya dapat dengan mudah membungkus daftar Python dalam kelas "Stackish" atau kelas "Queueish", itu tidak terlihat begitu mudah (atau efisien) untuk melakukan keduanya sekaligus.
Peter
-2

Push dan Pop masuk akal dalam hal metafora tumpukan piring atau nampan di kafetaria atau prasmanan, khususnya yang dalam jenis pemegang yang memiliki pegas di bawahnya sehingga pelat atas (kurang lebih ... dalam teori) di tempat yang sama tidak peduli berapa banyak piring di bawahnya.

Jika Anda mengeluarkan baki, berat pada pegas sedikit kurang dan tumpukan "sedikit" naik, jika Anda mengembalikan piring, itu "mendorong" tumpukan itu ke bawah. Jadi, jika Anda berpikir tentang daftar sebagai tumpukan dan elemen terakhir sebagai yang teratas, maka Anda tidak akan memiliki banyak kebingungan.

bob
sumber