Beim Formatieren einer Zeichenfolge wird derselbe Wert mehrmals eingefügt


111

Ich habe eine Zeichenfolge dieser Form

s='arbit'
string='%s hello world %s hello world %s' %(s,s,s)

Alle% s in der Zeichenfolge haben den gleichen Wert (dh s). Gibt es eine bessere Art, dies zu schreiben? (Anstatt s dreimal aufzulisten)



2
Dieser %Zeichenfolgenoperator wird in Python 3.1 "veraltet und später entfernt" docs.python.org/release/3.0.1/whatsnew/…. Jetzt frage ich mich, was sowohl für die Versionskompatibilität als auch für die Sicherheit der am besten empfohlene Weg ist.
Cregox

2
@Cawas Ich weiß, dass dies ziemlich spät ist, aber ich benutze es gerne str.format(). Beispiel: query = "SELECT * FROM {named_arg}"; query.format(**kwargs)Wo queryist die Formatzeichenfolge und kwargsist ein Wörterbuch mit Schlüsseln, die mit den named_args in der Formatzeichenfolge übereinstimmen .
Edwin

4
@Cawas Ja, außer Adam Tupels Notation verwendet, wobei {0}, {1}, {2}und so weiter , entsprechen Tupels Indizes 0, 1und 2, respectively. Alternativ ist es auch möglich, die Argumente (wie {named_arg}) zu benennen und jedes in der Formatmethode festzulegen, wie folgt:'Hi {fname} {lname}!'.format(fname='John', lname='Doe')
Edwin

2
@bignose Sie haben beide Fragen Duplikate voneinander markiert, es ist wie google.com/…
abhi

Antworten:



40
incoming = 'arbit'
result = '%(s)s hello world %(s)s hello world %(s)s' % {'s': incoming}

Vielleicht möchten Sie dies lesen, um ein Verständnis zu erlangen: Zeichenfolgenformatierungsvorgänge .


1
Nett. Hatte das vergessen. Einheimische () werden es auch tun.
Goutham

2
@Goutham: Die Antwort von Adam Rosenfield könnte besser sein, wenn Ihre Python-Version auf dem neuesten Stand ist.
Mhawke

Es ist tatsächlich. Ich gewöhne mich immer noch an die neuen Formatierungsvorgänge für Zeichenfolgen.
Goutham

3
Noch besser, Sie können die Basiszeichenfolge multiplizieren: '% (s) s Hallo Welt' * 3% {'s': 'asdad'}
dalloliogm

15

Sie können den Wörterbuch-Formatierungstyp verwenden:

s='arbit'
string='%(key)s hello world %(key)s hello world %(key)s' % {'key': s,}

1
Es scheint sehr wenig Sinn zu machen, diese doppelte Antwort zu geben. Hier ist noch eine: '% (string_goes_here) Hallo Welt% (string_goes_here) Hallo Welt% (string_goes_here)'% {'string_goes_here': s,}. Es gibt praktisch unendlich viele Möglichkeiten.
Mhawke

3
mhawke: Ich habe die Nachricht gepostet, bevor mein Browser die Seite neu lädt, sodass ich zu diesem Zeitpunkt nicht wusste, dass die Frage bereits beantwortet wurde. Du musst kein unhöflicher Mann sein !!
Lucas S.

2
@Lucas: Ich nehme an, es ist möglich, dass du 13 Minuten gebraucht hast, um deine Antwort einzugeben :) und danke für die Abwertung ... sehr geschätzt.
Mhawke

13

Kommt darauf an, was du mit besser meinst. Dies funktioniert, wenn Ihr Ziel die Beseitigung von Redundanz ist.

s='foo'
string='%s bar baz %s bar baz %s bar baz' % (3*(s,))

3
>>> s1 ='arbit'
>>> s2 = 'hello world '.join( [s]*3 )
>>> print s2
arbit hello world arbit hello world arbit

Ich denke, dass das Beispiel in der Frage nicht über "Hallo Welt" wiederholt wurde, sondern eine echte Vorlage ohne Duplizierung. Deshalb habe ich abgelehnt.
Gra

1

Fstrings

Wenn Sie verwenden Python 3.6+, können Sie die neue so genannte f-stringsZeichenfolge verwenden, die für formatierte Zeichenfolgen steht. Sie können sie verwenden, indem Sie das Zeichen fam Anfang einer Zeichenfolge hinzufügen , um diese als F-Zeichenfolge zu identifizieren .

price = 123
name = "Jerry"
print(f"{name}!!, {price} is much, isn't {price} a lot? {name}!")
>Jerry!!, 123 is much, isn't 123 a lot? Jerry!

Die Hauptvorteile der Verwendung von F-Strings bestehen darin, dass sie besser lesbar sind, schneller sind und eine bessere Leistung bieten:

Quellpandas für alle: Python-Datenanalyse, Von Daniel Y. Chen

Benchmarks

Kein Zweifel, dass die neuen f-stringsbesser lesbar sind, da Sie die Zeichenfolgen nicht neu zuordnen müssen, aber ist es schneller, wie im oben genannten Zitat angegeben?

price = 123
name = "Jerry"

def new():
    x = f"{name}!!, {price} is much, isn't {price} a lot? {name}!"


def old():
    x = "{1}!!, {0} is much, isn't {0} a lot? {1}!".format(price, name)

import timeit
print(timeit.timeit('new()', setup='from __main__ import new', number=10**7))
print(timeit.timeit('old()', setup='from __main__ import old', number=10**7))
> 3.8741058271543776  #new
> 5.861819514350163   #old

Mit 10 Millionen Tests scheint es, dass die neuen f-stringstatsächlich schneller im Mapping sind.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.