Perché gli elenchi di Python hanno pop () ma non push ()


265

Qualcuno sa perché la list.appendfunzione di Python non viene chiamata list.pushdato che esiste già un list.popelemento che rimuove e restituisce l'ultimo elemento (che è indicizzato a -1) e che la list.appendsemantica è coerente con quell'uso?


21
<nitpick> È un metodo, non una funzione. </nitpick>
Tim Pietzcker,

49
Penso che questa sia un'ottima domanda, anche se forse dovrebbe essere formulata: "Perché gli elenchi di Python hanno pop () ma non push ()".
Uri,

6
poppuò estrarre elementi da qualsiasi parte in un elenco. appendimpossibile "spingere" qualcosa nel mezzo di un elenco.
endolith,

@TimPietzcker <nitpick ^ 2> Il metodo è, in effetti, anche una funzione, il metodo (funzione membro) è un sottoinsieme della funzione :)
jave.web

Risposte:


246

Perché "append" esisteva molto prima che si pensasse a "pop". Python 0.9.1 supporta list.append all'inizio del 1991. In confronto, ecco parte di una discussione su comp.lang.python sull'aggiunta di pop nel 1997. Guido ha scritto:

Per implementare uno stack, è necessario aggiungere una primitiva list.pop () (e no, non sono contrario a questo in particolare sulla base di un principio). list.push () potrebbe essere aggiunto per simmetria con list.pop () ma non sono un grande fan di più nomi per la stessa operazione - prima o poi leggerai il codice che utilizza l'altro, quindi devi imparare entrambi, che è più carico cognitivo.

Puoi anche vedere che discute dell'idea se push / pop / put / pull dovrebbe essere nell'elemento [0] o dopo l'elemento [-1] dove pubblica un riferimento all'elenco di Icon:

Penso che tutto ciò sia meglio fuori dall'implementazione dell'oggetto elenco - se hai bisogno di uno stack o di una coda, con una semantica particolare, scrivi una piccola classe che utilizza un elenco

In altre parole, per gli stack implementati direttamente come elenchi Python, che già supporta veloce append () e del list [-1], ha senso che list.pop () funzioni di default sull'ultimo elemento. Anche se altre lingue lo fanno diversamente.

Qui è implicito che la maggior parte delle persone ha bisogno di aggiungere un elenco, ma molti meno hanno occasione di trattare gli elenchi come stack, motivo per cui list.append è arrivato molto prima.


16
@poige you're going to *read* code that uses the other one (...) which is more cognitive loadRicordare che "non c'è spinta" introduce il carico cognitivo solo quando scrivi il codice. Ricordare "push è un sinonimo esatto di append" introduce un carico cognitivo ogni volta che leggi quello che vedi usato meno spesso. Vedi stackoverflow.com/questions/3455488/… per ulteriori informazioni sul motivo per cui le persone pensano che la leggibilità spesso superi la scrivibilità
stevenjackson121

2
Non ha nessuna scusa / senso
poige

15

Perché si aggiunge; non spinge. "Aggiunta" aggiunge alla fine di un elenco, "spingendo" aggiunge in primo piano.

Pensa a una coda contro una pila.

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

Modifica: per riformulare la mia seconda frase in modo più preciso, "Aggiungere" implica chiaramente aggiungere qualcosa alla fine di un elenco, indipendentemente dall'implementazione sottostante. Dove un nuovo elemento viene aggiunto quando viene "spinto" è meno chiaro. Il push su uno stack sta mettendo qualcosa in "top", ma dove si colloca effettivamente nella struttura di dati sottostante dipende completamente dall'implementazione. D'altra parte, spingere su una coda implica aggiungerlo alla fine.


4
Il tutorial sembra suggerire che semplicemente spinge e salta dalla fine: "I metodi dell'elenco rendono molto facile usare un elenco come uno stack, in cui l'ultimo elemento aggiunto è il primo elemento recuperato (" last-in, first-out "). Per aggiungere un oggetto in cima alla pila, usa append (). Per recuperare un oggetto dalla cima della pila, usa pop () senza un indice esplicito."
Uri,

110
"spingere" in nessun modo significa aggiungere alla parte anteriore. ogni implementazione di uno stack che sia mai stata scritta da una persona sana "spinge" nella parte superiore (fine) dello stack, non nella parte inferiore (inizio) dello stack
Kip

4
correzione: ogni * implementazione basata su array . un'implementazione dell'elenco collegato spingerebbe alla testa.
Kip

16
javascript pushaggiunge alla fine.
Kobi,

2
No, tenendo conto della list.popsemantica, list.appendinserisce gli elementi nell'elenco, se visualizzati come stack.
fortran,

10

Perché aggiunge un elemento a un elenco? La spinta viene generalmente utilizzata quando si fa riferimento a pile.


7
Un elenco può essere comunque uno stack. :-)
Jason Baker,

@JasonBaker È possibile implementare uno stack utilizzando un elenco, ma ciò non significa list == stack. Puoi anche implementare uno stack usando una coda, se lo desideri davvero. (Sarebbe terribilmente inefficiente, ma è possibile!)
Mark E. Haase,

La confusione deriva dal fatto che uno stack non ha un "inizio" o una "fine" come una lista, ma piuttosto un "inizio" e un "ultimo". Aggiungere alla pila implica posizionare un elemento in alto e "spingere" verso il basso. "Spingere" davanti non ha senso (almeno non linguisticamente). E solo per rendere le cose ancora più confuse, C ++ usa "push_front" e "push_back".
JesperE,

9

Perché "aggiungi" significa intuitivamente "aggiungi alla fine dell'elenco". Se si chiamasse "push", non sarebbe chiaro se stiamo aggiungendo elementi in coda o in testa alla lista.


12
Questo non ha senso poiché c'è popun'operazione. Dato che pushe popsono in genere operazioni di stack e vanno insieme, ci si dovrebbe aspettare che operino sulla stessa estremità dell'elenco.
jamesdlin,

7

Non è una risposta ufficiale in alcun modo (solo un'ipotesi basata sull'uso della lingua), ma Python ti consente di utilizzare gli elenchi come pile (ad esempio, la sezione 5.1.1 del tutorial ). Tuttavia, un elenco è ancora prima di tutto un elenco, quindi le operazioni comuni a entrambi usano termini di elenco (ad es. Append) anziché termini di stack (ad es. Push). Poiché un'operazione pop non è così comune negli elenchi (anche se avrebbe potuto essere usato 'removeLast'), hanno definito un pop () ma non un push ().


3

Ok, opinione personale qui, ma Append e Prepend implicano posizioni precise in un set.

Push e Pop sono in realtà concetti che possono essere applicati a entrambe le estremità di un set ... Finché sei coerente ... Per qualche motivo, per me, Push () sembra che dovrebbe applicarsi alla parte anteriore di un impostato...


3
Da quando lo hai visualizzato, se gli array hanno una funzione .append (), allora perché non esiste alcuna funzione corrispondente.prepend ()? Posso imparare a usare .insert (0, val) per anteporre, ma sono poi imbarazzato dalla mancanza di una corrispondente funzione .delete (pos, val). rif: docs.python.org/2/library/array.html
MarkHu

3

Cordiali saluti, non è tremendamente difficile fare una lista che ha un metodo 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]

Una pila è un tipo di dati piuttosto astratto. L'idea di "spingere" e "fare scoppiare" sono in gran parte indipendenti dal modo in cui lo stack è effettivamente implementato. Ad esempio, potresti teoricamente implementare uno stack come questo (anche se non so perché lo faresti):

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

... e non ho iniziato a usare elenchi collegati per implementare uno stack.


1

Il push è un comportamento dello stack definito ; se spingessi A per impilare (B, C, D) otterrai (A, B, C, D).

Se hai usato append python, il set di dati risultante sarebbe simile (B, C, D, A)

Modifica: Wow, pedanteria santa.

Suppongo che dal mio esempio sarebbe chiaro quale parte dell'elenco è in cima e quale parte è in fondo. Supponendo che la maggior parte di noi qui legga da sinistra a destra, il primo elemento di qualsiasi elenco sarà sempre sulla sinistra.


1
Questo non è vero, il pop viene rimosso dalla fine dell'elenco, non dalla parte anteriore.
fortran,

4
leggi la pagina a cui ti colleghi. push è definito come push nella parte superiore della pila. quale fine è il "top" dipende dall'implementazione. in uno stack basato su array, push spingerebbe fino alla fine dell'array. in uno stack basato su elenchi collegati, push spingerebbe all'inizio.
Kip

0

Probabilmente perché la versione originale di Python ( C Python) era scritta in C, non in C ++.

L'idea che un elenco sia formato spingendo le cose sul retro di qualcosa probabilmente non è così noto come l'idea di aggiungerle.


La seconda parte è una buona risposta. Ma cosa c'entra questo con l'implementazione in C / C ++?
Jason Baker,

@Jason: Nell'STL di C ++, push_back () è il modo in cui si aggiunge a un elenco. Stavo cercando di trasmettere la meta-idea che l'idea che gli elenchi si formino spingendo è forse più probabile che si apra se stai lavorando in C ++. Ha un senso?
Rilassati il

Se hai un tipo di elenco implementato come un array contiguo (un vettore in C ++, un elenco in Python, un array in Perl), ha senso che "push" metta il nuovo elemento alla fine. Noterai che perl 4 suppone "push" e "pop" come funzioni su array esattamente come l'appendice / pop di Python e il push_back / pop_back di C ++, e ben prima che STL fosse formalmente proposto a C ++. Quindi non ha nulla a che fare con la STL di C ++ che crea una nuova comprensione delle cose.
Andrew Dalke,

Una delle cose che mi manca imparare Python da uno sfondo Perl è la capacità di usare le operazioni push (), pop (), shift () e unshift () integrate per aggiungere / rimuovere elementi da / verso una delle estremità dello stesso matrice . Anche se posso facilmente avvolgere un elenco Python in una classe "Stackish" o in una classe "Queueish", non sembra così facile (o efficiente) fare entrambe le cose contemporaneamente.
Peter,

-2

Push e Pop hanno senso in termini di metafora di una pila di piatti o vassoi in una caffetteria o in un buffet, in particolare quelli nel tipo di supporto che ha una molla sotto quindi la piastra superiore è (più o meno ... in teoria) nello stesso posto, non importa quante piastre ci siano sotto.

Se si rimuove un vassoio, il peso sulla molla è un po 'meno e la risma "si solleva" leggermente, se si ripone il piatto, si "spinge" verso il basso la risma. Quindi, se pensi all'elenco come uno stack e l'ultimo elemento è in cima, non dovresti avere molta confusione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.