Perché% s è meglio di + per la concatenazione?


88

Capisco che dovremmo usare %sper concatenare una stringa piuttosto che +in Python.

Potrei fare uno qualsiasi di:

hello = "hello"
world = "world"

print hello + " " + world
print "%s %s" % (hello, world)
print "{} {}".format(hello, world)
print ' '.join([hello, world])

Ma perché dovrei usare qualcosa di diverso da +? È più veloce scrivere concatenazione con un semplice +. Quindi se guardi la stringa di formattazione, specifichi i tipi eg %se %de simili. Capisco che potrebbe essere meglio essere espliciti sul tipo.

Ma poi ho letto che l'uso +per la concatenazione dovrebbe essere evitato anche se è più facile da scrivere. C'è una chiara ragione per cui le stringhe dovrebbero essere concatenate in uno di questi altri modi?


29
Chi ti ha detto che è meglio?
yannis,

3
%snon è per la concatenazione, è una specifica di conversione per la formattazione di stringhe derivata da C's printf(3). Ci sono casi da utilizzare per questo o un operatore di concatenazione; che usi dovrebbe essere basato sul giudizio della situazione, non sul dogma. Quanto è facile scrivere il codice è del tutto irrilevante perché lo farai solo una volta.
Blrfl,

Ho nuovo fulcro la domanda a proprio python (anche se io non sono una persona pitone e ci potrebbe essere ancora difetti nel codice). Assicurati che questa sia la domanda che stai ponendo, effettua gli aggiornamenti appropriati e considera di porre una domanda diversa se sei interessato a C o Java.

12
E ora abbiamo le corde f superiori ! print(f"{hello} {world}"), ha la leggibilità della concatenazione poiché le variabili sono viste dove si trovano nella stringa ed è più veloce di str.format.
Enrico Borba,

Risposte:


88
  1. Leggibilità. La sintassi della stringa di formato è più leggibile, in quanto separa lo stile dai dati. Inoltre, in Python, la %ssintassi forzerà automaticamente qualsiasi non strtipo str; mentre la concatenazione funziona solo con str, e non è possibile concatenare strcon int.

  2. Prestazione. In Python strè immutabile, quindi la stringa sinistra e destra devono essere copiate nella nuova stringa per ogni coppia di concatenazione. Se concatenate quattro stringhe di lunghezza 10, copierete (10 + 10) + ((10 + 10) +10) + (((10 + 10) +10) +10) = 90 caratteri, anziché solo 40 personaggi. E le cose peggiorano quadraticamente all'aumentare del numero e della dimensione della stringa. Java ottimizza questo caso alcune volte trasformando la serie di concatenazioni da usare StringBuilder, ma CPython no.

  3. Per alcuni casi d'uso, la libreria di registrazione fornisce un'API che utilizza la stringa di formato per creare pigramente la stringa della voce di registro ( logging.info("blah: %s", 4)). Questo è ottimo per migliorare le prestazioni se la libreria di registrazione ha deciso che la voce di registro corrente verrà scartata da un filtro di registro, quindi non è necessario formattare la stringa.


31
hai qualche fonte scientifica o empirica per il n. 1? Perché penso che sia molto meno leggibile (specialmente con più di 2 o tre argomenti)
Lovis,

4
@ L.Möller: Non sono sicuro del tipo di fonte che ti aspetti da un'esperienza soggettiva (facilità di lettura), ma se vuoi il mio ragionamento: 1)% s richiede 2 caratteri extra per segnaposto vs + richiede minimo 4 (o 8 se segui PEP8, 13 se costringi), 2)% s è racchiuso in una singola stringa, quindi è più facile analizzare visivamente, con +, hai più parti mobili: chiudi stringa, operatore, variabile , operatore, stringa aperta, 3) colorazione della sintassi% s ha un colore per ciascuna funzione: stringa e segnaposto, con + ottieni tre colorazioni: stringa, operatore e colorazione variabile.
Lie Ryan,

4
@ L.Möller: 4) Ho la possibilità di inserire stringhe di formato più lunghe in una variabile o in un dizionario, lontano da dove è necessario eseguire la formattazione, 5) la stringa di formato può essere specificata dall'utente da un file di configurazione, args di comando o database , lo stesso non si può dire con le concatenazioni. Ma sì, anche io non userei% s quando ho più di 4-5 cose da interpolare, invece userei la variante% (varname) s o "{foo}". Format () in Python. Penso che i nomi espliciti migliorino la leggibilità per stringhe di formato più lunghe con molte variabili interpolate.
Lie Ryan,

2
Non so cosa sia "vero", ecco perché ti chiedo se hai delle prove :-). Sono davvero d'accordo con il tuo secondo commento
Lovis il

6
Trovo che il numero 2 sia sospetto - hai prove documentate? Non ho molta familiarità con Java, ma nella concatenazione in C # è più veloce dell'interpolazione di stringhe . Sono completamente d'accordo con il n. 1 e mi affido davvero a quello per decidere quando usare quale, ma bisogna ricordare che l'interpolazione richiede una quantità di analisi delle stringhe e complessità dove la concatenazione non richiede nulla di tutto ciò.
Jimmy Hoffa,

48

Sono l'unico che legge da sinistra a destra?

Per me usare %sè come ascoltare chi parla tedesco, dove devo aspettare fino alla fine di una lunghissima frase per sentire qual è il verbo.

Quale di questi è più chiaro a colpo d'occhio?

"your %s is in the %s" % (object, location)

o

"your " + object + " is in the " + location  

17
Ovviamente questo è soggettivo, poiché trovo il primo più leggibile - e più facile da scrivere e modificare. Il secondo mescola il testo con un codice che oscura entrambi e aggiunge rumore. Ad esempio, è facile sbagliare gli spazi nel secondo.
JacquesB,

5
@JacquesB In realtà penso che il tuo cervello sia così familiare con questo formato che salti immediatamente tra parentesi e stai sostituendo le parole all'istante. Tecnicamente non è una lettura da sinistra a destra, ma va benissimo. Trovo che lo faccia anche io, quindi sì, 1 è più facile da leggere perché so che devo affrontare problemi di spaziatura stupidi prima e dopo le virgolette nel secondo, ed è molto lento con cui lavorare.
Nelson,

3
Dopo ndecenni, anche la mia mente funziona in questo modo ;-) Ma resto ancora dalla mia risposta, la seconda è più chiara e più facile da leggere, quindi da mantenere. E questo diventa più evidente più parametri hai. Alla fine, se si tratta di uno spettacolo individuale, vai con ciò che conosci e con cui ti senti a tuo agio; se si tratta di uno sforzo di gruppo, imporre coerenza e revisioni del codice; le persone possono abituarsi.
Mawg,

4
Il primo è molto più leggibile per me perché ha meno "trapianto" nel mezzo della frase. È più facile per il mio occhio dare un'occhiata alla fine, quindi spetta al mio cervello analizzare le citazioni, gli spazi e i vantaggi extra. Naturalmente, ora preferisco molto di Python stringhe di formato 3.6: f"your {object} is in the {location}".
Dustin Wyatt,

8
Trovo anche più difficile leggere e scrivere quando la variabile deve essere racchiusa tra virgolette. "your '" + object + "' is in the '" + location + "'"... Non sono nemmeno sicuro di averlo capito subito ...
Dustin Wyatt il

12

Un esempio che chiarisce l'argomento leggibilità:

print 'id: ' + id + '; function: ' + function + '; method: ' + method + '; class: ' + class + ' -- total == ' + total

print 'id: %s; function: %s; method: %s; class: %s --total == %s' % \
   (id, function, method, class, total)

(Nota che il secondo esempio non è solo più leggibile ma anche più facile da modificare, puoi cambiare il modello su una riga e un elenco di variabili su un'altra)

Un altro problema è che il codice% s converte anche nella stringa, altrimenti devi usare str () call che è anche meno leggibile di un codice% s.


1
Non sono d'accordo con la tua prima affermazione, ma possiamo essere d'accordo a dissentire, stavo per pubblicare una risposta sulla
falsa

6

L'uso non+ dovrebbe essere evitato in generale. In molti casi è l'approccio corretto. L'uso o è preferibile solo in casi particolari, ed è di solito abbastanza ovvio quando sono la soluzione migliore.%s.join()

Nel tuo esempio stai concatenando tre stringhe insieme, e l'esempio usando +è chiaramente il più semplice e leggibile, e quindi il raccomandato.

%so .format()sono utili se si desidera interpolare stringhe o valori nel mezzo di una stringa più grande. Esempio:

print "Hello %s, welcome to the computer!" % name

In questo caso il suo utilizzo %sè più leggibile poiché si evita di tagliare la prima stringa in più segmenti. Soprattutto se si interpolano più valori.

.join() è appropriato se si dispone di una sequenza di stringhe di dimensioni variabili e / o si desidera concatenare più stringhe con lo stesso separatore.


2

Poiché l'ordine delle parole può cambiare in diverse lingue, il modulo con %sè indispensabile se si desidera supportare correttamente la traduzione delle stringhe nel proprio software.

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.