2011-11-30 11 views
7
>>> b = [] 
>>> c = '1234' 
>>> b += c 
>>> b 
['1', '2', '3', '4'] 
>>> 

Che cosa sta succedendo qui? Questo non dovrebbe funzionare, giusto? o mi manca qualcosa di ovvio?Aggiungere una stringa a un elenco

>>> b = [] 
>>> c = '1234' 
>>> b + c 
Traceback (most recent call last): 
    File "<pyshell#7>", line 1, in <module> 
    b + c 
TypeError: can only concatenate list (not "str") to list 
>>> 

Poi a += b non è sempre equivalente a a = a + b?

+1

È questo comportamento ancora presenti in Python 3.x? Ho sempre trovato irritante il fatto che un tipo di libreria standard infrange il contratto generale che 'a + = b' <=>' a = a + b' (senza influire su altri riferimenti al valore originale 'a'). –

+2

@Karl Knechtel: sfortunatamente, è ancora presente in Python 3.2.1. –

+0

Lo stavo verificando in python 3.2, sì. Ho trovato il problema guardando un codice principiante che stava producendo risultati sbagliati. Non ho trovato alcun riferimento a questo comportamento specifico in 'Learning Python'. Ho controllato PEP203 e si dice che '__iadd__' è usato ma dicono anche che' __iadd__' è l'inplace '__add__' che non è il caso in questo caso ... Forse qualcuno potrebbe spiegare il razionale sotto questo comportamento o punto/collegamento ad alcune discussioni a riguardo? Capisco dal commento di Karl che ci sono persone a riguardo – joaquin

risposta

2

Una stringa è una sequenza di caratteri. L'operazione lista += esegue una sequenza qualsiasi e aggiunge tutti gli elementi della sequenza all'elenco.

(In realtà += prende ogni iterabile.)

+0

b = b + c fallisce – joaquin

+2

'+' è un operatore diverso da '+ ='. –

+0

Lo so, si chiama potenziamento e si definisce equivalente a a = a + b (vedi PEP203). Prendere questa definizione mi porta drasticamente ad un'aspettativa sbagliata. Questo è ciò che mi ha sorpreso (probabilmente non ho mai avuto il coraggio di aggiungere una lista a una stringa nel mio codice Python, quindi non l'ho mai messo in discussione prima). Non dovrebbe essere "Di fronte all'ambiguità, rifiutare la tentazione di indovinare"? – joaquin

11

Le stringhe sono iterabile: gli elementi sono caratteri della stringa. Quando aggiungi un iterabile a un elenco, gli elementi iterabili vengono aggiunti all'elenco.

Uno di quanto segue farà quello che ci si aspetta (cioè aggiungere la stringa, si estende la lista con i caratteri della stringa):

b += [c] 

o

b.append(c) 
+0

+1 per usare il vocabolario corretto: 'iterable' – gecco

9

Il += operatore si estende un elenco invece di aggiungere ad esso:

>>> b = [] 
>>> c = "1234" 
>>> b.append(c) 
>>> b 
['1234'] 
>>> b.extend(c) 
>>> b 
['1234', '1', '2', '3', '4'] 
>>> b += c 
>>> b 
['1234', '1', '2', '3', '4', '1', '2', '3', '4'] 
>>> b += [c] 
>>> b 
['1234', '1', '2', '3', '4', '1', '2', '3', '4', '1234'] 
+0

conosci una fonte di documentazione sull'effetto di questi operatori ('+', '+ =') per iterabili/sequenze/...? – moooeeeep

0

Cosa ti aspettavi? Se si desidera aggiungere c come stringa che si deve fare:

b.append(c) 

Cheers!

+0

Mi aspettavo che fallisse – joaquin

+0

Ma come Tim ha spiegato sopra il comportamento di + = non è lo stesso che + – ocell

+0

per favore, vedi commento su Tim post. – joaquin

0

In pratica, l'operatore + = nell'elenco recupera l'iteratore di c, che restituisce i singoli caratteri nell'ordine. Se intendevi aggiungere la stringa effettiva all'elenco, ottenendo il risultato ['1234'], puoi usare invece b.append ('1234').

2

+ = è lo zucchero sintattico per l'estensione, ma + è solo una lista di concatenazione. Se estendi, eseguirai l'iterazione sull'argomento, che in questo caso è una stringa. Ma non è possibile concatenare una stringa in un elenco, quindi + fallisce.

3

Questa è una risposta non alla domanda originale (a cui penso sia stata data una risposta adeguata), ma alle numerose domande che sono state poste nei commenti sulla semantica di assegnazione aumentata (+= e operazioni simili).

In breve: l'assegnazione aumentata funziona in modo diverso per i tipi mutabili rispetto a quelli immutabili.

str, tuple e i tipi numerici, tra gli altri, sono immutabili. Il contenuto di una tupla non possono essere modificati una volta che è stato creato, in modo da ottenere questo comportamento:

>>> a = (1, 2) 
>>> b = a 
>>> a += (3, 4) 
>>> a 
(1, 2, 3, 4) 
>>> b 
(1, 2) 

str ha la stessa semantica. Fondamentalmente, a += b equivale a a = a + b se a è immutabile.

La maggior parte degli altri tipi, incluso list, è modificabile.Il contenuto di una lista può essere modificato e l'assegnazione aumentata fa esattamente questo. Quindi:

>>> a = [1, 2] 
>>> b = a 
>>> a += [3, 4] 
>>> a 
[1, 2, 3, 4] 
>>> b 
[1, 2, 3, 4] 

Mentre se la terza linea sono stati sostituiti con a = a + [3, 4], una nuova lista verrebbe creata e b sarebbe [1, 2].

Per una classe definita dall'utente, la semantica dipendono da come è stato implementato, ma questo è il modo in cui dovrebbe essere fatto per PEP 203.

+0

Questa è davvero una buona osservazione. 'a' e' b' condividono lo stesso indirizzo di memoria finché 'a' non viene valutato sul lato sinistro di un operatore di assegnazione? Potresti includerlo? – Droogans

Problemi correlati