Operatore Python append () vs + sugli elenchi, perché questi danno risultati diversi?


113

Perché queste due operazioni ( append()rispettivamente +) danno risultati diversi?

>>> c = [1, 2, 3]
>>> c
[1, 2, 3]
>>> c += c
>>> c
[1, 2, 3, 1, 2, 3]
>>> c = [1, 2, 3]
>>> c.append(c)
>>> c
[1, 2, 3, [...]]
>>> 

Nell'ultimo caso c'è effettivamente una ricorsione infinita. c[-1]e csono la stessa cosa. Perché è diverso con l' +operazione?


1
con tutto il rispetto per una nuova domanda valida: sono tornato alla domanda originale per mantenerla pulita (1 domanda per thread, vedi SO FAQ). Si prega di chiederne uno nuovo o di porre domande di follow-up all'interno dei thread dei commenti sotto ogni risposta. Nota: le tue modifiche non vanno perse, fai clic sulla cronologia e puoi copiarla / incollarla in una nuova domanda.
Abel


sembra che dia risposte diverse, ma non così. Se vuoi aggiungere un valore usando l'operatore + devi usare il segno []. c + = [c] ti darà lo stesso risultato di append.
Sharif Chowdhury

@SharifChowdhury Credo che otterrai lo stesso risultato
fiducioso il

Risposte:


142

Per spiegare "perché":

L' +operazione aggiunge gli elementi dell'array all'array originale. L' array.appendoperazione inserisce l'array (o qualsiasi oggetto) alla fine dell'array originale, che si traduce in un riferimento a self in quel punto (da qui la ricorsione infinita).

La differenza qui è che l'operazione + agisce in modo specifico quando aggiungi un array (è sovraccarico come gli altri, vedi questo capitolo sulle sequenze) concatenando l'elemento. Il metodo append tuttavia fa letteralmente quello che chiedi: aggiungi l'oggetto sul lato destro che gli dai (l'array o qualsiasi altro oggetto), invece di prendere i suoi elementi.

Un'alternativa

Utilizzare extend()se si desidera utilizzare una funzione che agisce in modo simile all'operatore + (come anche altri hanno mostrato qui). Non è saggio fare il contrario: provare a imitare append con l'operatore + per gli elenchi (vedere il mio collegamento precedente sul perché).

Poca storia

Per divertimento, un po 'di storia: la nascita del modulo array in Python nel febbraio 1993. potrebbe sorprendervi, ma gli array sono stati aggiunti molto dopo che le sequenze e gli elenchi sono nati.


2
+1 perché ho sempre votato a favore di informazioni accurate. I link ai documenti ufficiali sono sempre un vantaggio!
jathanism

10
Un'altra parte del "perché": le persone sane si aspettano +di essere simmetriche: concatena lista con lista.
Beni Cherniavsky-Paskin

1
+1, Buona osservazione Beni (anche se potrei considerare altrettanto "sano" dire "l'oggetto sul lato destro è aggiunto all'array sul lato sinistro", ma personalmente trovo il comportamento corrente più sensato).
Abel

se un elemento è una singola stringa, ad es. s = 'word', l = ['this', 'is']. Quindi l.append (s) e l + s dovrebbero essere gli stessi. Ho ragione?
user3512680

23

L'operatore di concatenazione +è un operatore infisso binario che, applicato alle liste, restituisce una nuova lista contenente tutti gli elementi di ciascuno dei suoi due operandi. Il list.append()metodo è un mutatorsu listcui aggiunge il suo singolo objectargomento (nel tuo esempio specifico l'elenco c) all'oggetto list. Nel tuo esempio questo si traduce cnell'aggiunta di un riferimento a se stesso (da qui la ricorsione infinita).

Un'alternativa alla concatenazione "+"

Il list.extend()metodo è anche un metodo mutatore che concatena il suo sequenceargomento con il soggetto list. In particolare, aggiunge ciascuno degli elementi di sequencenell'ordine di iterazione.

A parte

Essendo un operatore, +restituisce il risultato dell'espressione come un nuovo valore. Essendo un mutatormetodo non concatenato , list.extend()modifica l'elenco degli argomenti sul posto e non restituisce nulla.

Array

L'ho aggiunto a causa della potenziale confusione che la risposta di Abele sopra potrebbe causare mescolando la discussione di elenchi, sequenze e array. Arrayssono stati aggiunti a Python dopo le sequenze e gli elenchi, come un modo più efficiente per archiviare array di tipi di dati integrali. Non confondere arrayscon lists. Non sono la stessa cosa.

Dai documenti dell'array :

Gli array sono tipi di sequenza e si comportano in modo molto simile agli elenchi, tranne per il fatto che il tipo di oggetti memorizzati in essi è vincolato. Il tipo viene specificato al momento della creazione dell'oggetto utilizzando un codice di tipo, che è un singolo carattere.


18

appendsta aggiungendo un elemento a un elenco. se vuoi estendere l'elenco con il nuovo elenco che devi utilizzare extend.

>>> c = [1, 2, 3]
>>> c.extend(c)
>>> c
[1, 2, 3, 1, 2, 3]

4
Ho pensato che fosse abbastanza chiaro il motivo per cui i risultati sono diversi, perché le operazioni non sono le stesse! se apparisse così +e extendproducesse risultati diversi a cui avremmo qualcosa a cui pensare.
SilentGhost

1
+1: Perché non mi piacciono le domande sul "perché": appende +sono diverse. Ecco perchè. Mi piace questa risposta perché offre ciò che fa che ha più senso.
S.Lott

Questo sito non si occupa di rispondere alle domande poste? Le persone chiedono perché PHP si chiama PHP e perché __lt__non può essere sovraccaricato in Python (al giorno d'oggi lo è). Le domande sul perché sono le più essenziali ma spesso le più difficili a cui rispondere: chiedono l'essenza, non un puntatore al manuale. E ovviamente: se una domanda non ti piace (a me non piace di più), allora non rispondere ;-)
Abel

Per ulteriore dimostrazione, forse spettacolo c += [c]e c.append(c[:])anche.
effimero

2
@Abel: Perché a+b != a*b? Sono operazioni diverse. Questa è la risposta. "Perché" non è utile quanto altre domande, come "Come posso aggiungere correttamente?" O "Cosa c'è di sbagliato in questa append che porta alla ricorsione infinita?" Domande del modulo "Cosa faccio a X" o "Cosa è andato storto quando ho fatto X"? Oppure "Cosa dovrei fare invece di X" aiuterà anche qualcuno a imparare, ma fornirà risposte mirate, utilizzabili e utilizzabili.
S.Lott

8

Le liste Python sono eterogenee, ovvero gli elementi nella stessa lista possono essere qualsiasi tipo di oggetto. L'espressione: c.append(c)aggiunge call'elenco qualunque cosa possa essere. Nel caso, rende la lista stessa un membro della lista.

L'espressione c += caggiunge due elenchi e assegna il risultato alla variabile c. L' +operatore di sovraccarico viene definito sugli elenchi per creare un nuovo elenco il cui contenuto sono gli elementi nel primo elenco e gli elementi nel secondo elenco.

Quindi queste sono in realtà solo espressioni diverse utilizzate per fare cose diverse in base alla progettazione.


7

Il metodo che stai cercando è extend(). Dalla documentazione di Python :

list.append(x)
    Add an item to the end of the list; equivalent to a[len(a):] = [x].

list.extend(L)
    Extend the list by appending all the items in the given list; equivalent to a[len(a):] = L.

list.insert(i, x)
    Insert an item at a given position. The first argument is the index of the element before which to insert, so a.insert(0, x) inserts at the front of the list, and a.insert(len(a), x) is equivalent to a.append(x).


2

Consulta la documentazione :

list.append (x)

  • Aggiungi un elemento alla fine dell'elenco; equivalente a a [len (a):] = [x].

list.extend (L) - Estende l'elenco aggiungendo tutti gli elementi nell'elenco fornito; equivalente a a [len (a):] = L.

c.append(c)"aggiunge" c a se stesso come elemento . Poiché un elenco è un tipo di riferimento, viene creata una struttura dati ricorsiva.

c += cè equivalente a extend(c), che aggiunge gli elementi di c a c.

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.