2009-10-14 7 views
222

Qualcuno sa perché la funzione list.append di Python non è chiamata list.push dato che c'è già un list.pop che rimuove e restituisce l'ultimo elemento (che indicizzato a -1) e la semantica list.append è coerente con tale uso?Perché "append" di Python non "spinge"?

+20

È un metodo, non una funzione.

+46

Penso che questa sia una grande domanda, anche se forse dovrebbe essere formulata: "Perché le liste python hanno pop() ma non push()". – Uri

+5

'pop' può far uscire oggetti da qualsiasi posizione in un elenco. 'append' non può" spingere "qualcosa nel mezzo di una lista. – endolith

risposta

212

Perché "append" esisteva molto tempo prima che si ritenesse "pop". Python 0.9.1 supportato list.append nei primi mesi del 1991. In confronto, ecco parte di una discussion on comp.lang.python sull'aggiunta pop nel 1997. Guido ha scritto:

Per implementare uno stack, uno avrebbe bisogno per aggiungere un list.pop() primitiva (e no, non sono contro questo particolare uno sulla base di qualsiasi principio). list.push() potrebbe essere aggiunto per la 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 è necessario imparare entrambi, che è più carico cognitivo.

Inoltre potrai vedere discute l'idea di se push/pop/put/trazione devono essere a elemento [0] o dopo elemento [-1] dove si distacca un riferimento alla lista di Icon:

ho stil pensare che tutto questo è meglio lasciati fuori dell'oggetto lista realizzazione - se avete bisogno di una pila, o una coda, con particolari la semantica, scrivere un po 'di classe che utilizza un liste

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

In questo caso è implicito che la maggior parte delle persone debba aggiungere a una lista, ma molti meno hanno l'occasione di trattare gli elenchi come stack, motivo per cui list.append è arrivato molto prima.

+15

Mi piace questa parte di "carico cognitivo". Quindi ora devi ricordare che c'è append(), e non c'è push(). Nessun carico, vero? – poige

+4

@poige 'stai andando a * leggere * codice che utilizza l'altro (...) che è più carico cognitivo' Ricordando" non c'è push "introduce solo carico cognitivo quando si scrive codice. Ricordando che "push è un sinonimo esatto di append" introduce il carico cognitivo ogni volta che leggi quello che vedi usato meno spesso. Vedi http://stackoverflow.com/questions/3455488/code-is-read-more-than-it-is-written per ulteriori informazioni sul motivo per cui le persone pensano che la leggibilità spesso superi la scrivibilità – stevenjackson121

+0

Non fa scusa/senso – poige

12

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

Pensa a una coda rispetto a una pila.

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

Edit: di riformulare la mia seconda frase, più esattamente, "aggiungendo" implica molto chiaramente aggiungendo qualcosa alla fine di un elenco, indipendentemente dalla implementazione sottostante. Dove viene aggiunto un nuovo elemento quando è "spinto" è meno chiaro. Spingersi su una pila significa mettere qualcosa in "alto", ma dove effettivamente va nella struttura dati sottostante dipende completamente dall'implementazione. D'altra parte, spingendo su una coda implica l'aggiunta alla fine.

+4

Il tutorial sembra suggerire che spinge in modo semplice e si apre dalla fine: "I metodi delle liste rendono molto facile da usare una lista come una pila, in cui l'ultimo elemento aggiunto è il primo elemento recuperato (“last-in, di prima out”). per aggiungere un elemento in cima alla pila, uso append(). per recuperare un elemento dalla cima della pila, utilizzare pop() senza un indice esplicito." – Uri

+92

'spingendo' in nessun modo significa aggiungere davanti. ogni implementazione di una pila che sia mai stato scritto da una persona sana "spinge" sulla parte superiore (fine) della pila, non il fondo (inizio) della pila – Kip

+4

* correzione: ogni * basata su array * attuazione. un'implementazione di liste collegate spingerebbe alla testa. – Kip

10

Perché aggiunge un elemento a un elenco? La spinta è solitamente usata quando si fa riferimento alle pile.

+6

Una lista può essere una pila però. :-) –

+0

@JasonBaker È possibile implementare uno stack utilizzando un elenco, ma ciò non significa lista == stack. Potresti anche implementare uno stack usando una coda, se proprio volessi. (Sarebbe terribilmente inefficiente, ma è possibile!) –

+0

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

0

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

L'idea che una lista sia formata spingendo le cose sul retro di qualcosa probabilmente non è nota come l'idea di aggiungerle.

+0

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

+0

@Jason: in 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 le liste siano formate premendo è forse più probabile che compaia se stai lavorando in C++. Ha senso? – unwind

+0

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

9

Perché "append" indica intuitivamente "aggiungi alla fine dell'elenco". Se fosse chiamato "push", non sarebbe chiaro se stiamo aggiungendo roba in coda o in testa alla lista.

+8

Questo non ha senso dato che c'è un'operazione 'pop'. Poiché 'push' e' pop' sono in genere operazioni di stack e vanno insieme, è normale che funzionino sulla stessa estremità dell'elenco. – jamesdlin

-1

Push è un comportamento definito stack; se avessi premuto A per impilare (B, C, D) avresti ottenuto (A, B, C, D).

Se è stato utilizzato pitone di aggiunta, il set di dati risultante sarebbe simile (B, C, D, A)

Edit: Wow, santo pedanteria.

Suppongo che dal mio esempio risulterebbe chiaro quale parte dell'elenco sia la parte superiore e quale parte sia la parte inferiore. Supponendo che la maggior parte di noi qui legga da sinistra a destra, il primo elemento di ogni lista sarà sempre sulla sinistra.

+0

Non è vero, pop si rimuove dalla fine dell'elenco, non dalla parte anteriore. – fortran

+4

leggi la pagina a cui ti colleghi. la spinta è definita come spinta in cima alla pila. quale fine è il "top" dipende dall'implementazione. in uno stack basato su array, push spingerebbe verso la fine dell'array. in uno stack basato su una lista collegata, push spingerebbe all'inizio. – Kip

+2

Ottieni una risposta da me per compensare i downvotes non necessari. – AndyPerfect

7

Non è una risposta ufficiale con qualsiasi mezzo (solo un'ipotesi basata sull'uso della lingua), ma Python consente di utilizzare elenchi come stack (ad es., section 5.1.1 of the tutorial). Tuttavia, una lista è ancora prima di tutto una lista, quindi le operazioni che sono comuni ad entrambi usano i termini della lista (cioè, append) piuttosto che i termini dello stack (cioè, push). Dal momento che un'operazione pop non è così comune negli elenchi (anche se "removeLast" avrebbe potuto essere usato), hanno definito un pop() ma non un push().

3

Ok, opinione personale qui, ma Append and Prepend implica posizioni precise in un set.

Push e Pop sono davvero concetti che possono essere applicati a entrambe le estremità di un set ... Fintanto che sei coerente ... Per qualche ragione, per me, Push() sembra che dovrebbe applicarsi a la parte anteriore di un set ...

+3

Dal momento che l'hai richiamato, se gli array hanno una funzione .append(), allora perché non esiste una 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). ref: http://docs.python.org/2/library/array.html – MarkHu

3

FYI, non è terribilmente 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] 

Uno stack è un tipo di dati un po 'astratto. L'idea di "spingere" e "scoppiare" sono in gran parte indipendenti dal modo in cui lo stack viene effettivamente implementato. Ad esempio, si potrebbe teoricamente implementare uno stack del genere (anche se non so perché si farebbe):

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

... e non ho ottenuto ad utilizzare liste collegate per implementare uno stack.

-1

Push e Pop hanno senso in termini di metafora di una pila di piatti o vassoi in una caffetteria o buffet, in particolare quelli in tipo di supporto che ha una molla sotto così il piatto 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 'inferiore e lo stack si "schizza" leggermente verso l'alto, se si rimette il piatto, esso "spinge verso il basso". Quindi se pensi che la lista sia una pila e l'ultimo elemento sia in cima, non dovresti avere molta confusione.