Wstawianie tej samej wartości wiele razy podczas formatowania ciągu


111

Mam ciąg tego formularza

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

Wszystkie% sw ciągu mają tę samą wartość (tj. S). Czy jest lepszy sposób na napisanie tego? (Zamiast wymieniać się trzy razy)



2
Ten %operator łańcuchowy będzie „przestarzały w Pythonie 3.1 i później zostanie kiedyś usunięty” docs.python.org/release/3.0.1/whatsnew/… teraz zastanawiam się, jaki jest najbardziej zalecany sposób zarówno dla zgodności wersji, jak i bezpieczeństwa.
cregox

2
@Cawas Wiem, że to dość późno, ale lubię używać str.format(). Np .: query = "SELECT * FROM {named_arg}"; query.format(**kwargs), gdzie queryjest ciągiem formatu i kwargsjest słownikiem z kluczami pasującymi do named_args w ciągu formatu.
Edwin

4
@Cawas Tak, z wyjątkiem Adama wykorzystywane krotny notacji, gdzie {0}, {1}, {2}i tak dalej odpowiadać indeksów krotki 0, 1i 2, odpowiednio. Alternatywnie, można również nazwać argumenty (takie jak {named_arg}) i ustawić każdy z nich w metodzie format, na przykład:'Hi {fname} {lname}!'.format(fname='John', lname='Doe')
Edwin

2
@bignose Oznaczyłeś oba pytania jako duplikaty siebie, tak jak google.com/ ...
abhi

Odpowiedzi:


203

Możesz użyć zaawansowanego formatowania ciągów , dostępnego w Pythonie 2.6 i Pythonie 3.x:

incoming = 'arbit'
result = '{0} hello world {0} hello world {0}'.format(incoming)

11
~ moje osobiste preferencje, wybierz styl kwargsresult = '{st} hello world {st} hello world {st}'.format(st=incoming)
nehem

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

Możesz przeczytać to, aby zrozumieć: Operacje formatowania ciągów .


1
Miły. Zapomniał o tym. locals () też się nada.
Goutham

2
@Goutham: Odpowiedź Adama Rosenfielda może być lepsza, jeśli Twoja wersja Pythona jest aktualna.
mhawke

To jest właściwie. Nadal przyzwyczajam się do nowych operacji formatowania ciągów.
Goutham

3
nawet lepiej, możesz pomnożyć ciąg podstawowy: '% (s) s hello world' * 3% {'s': 'asdad'}
dalloliogm

15

Możesz użyć formatowania typu słownikowego:

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

1
Wydaje się, że udzielenie tej podwójnej odpowiedzi nie ma większego sensu. Oto kolejny: '% (string_goes_here) s hello world% (string_goes_here) s hello world% (string_goes_here) s'% {'string_goes_here': s,}. Możliwości jest praktycznie nieskończona.
mhawke

3
mhawke: opublikowałem wiadomość, zanim moja przeglądarka ponownie załaduje stronę, więc nie wiedziałem wtedy, że odpowiedź na pytanie została już udzielona. Nie musisz być niegrzeczny !!.
Lucas S.

2
@Lucas: Przypuszczam, że wpisanie odpowiedzi zajęło Ci 13 minut :) i dziękuję za głos negatywny… bardzo doceniane.
mhawke

13

Zależy, co masz na myśli mówiąc lepiej. Działa to, jeśli Twoim celem jest usunięcie nadmiarowości.

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

Wydaje mi się, że przykład w pytaniu nie dotyczył powtórki „hello world”, ale prawdziwego szablonu bez duplikatów. Dlatego przegłosowałem.
Gra,

1

Struny

Jeśli używasz Python 3.6+, możesz skorzystać z nowego tzw., f-stringsCo oznacza sformatowane ciągi znaków i można go użyć, dodając znak fna początku ciągu, aby zidentyfikować go jako f-string .

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!

Głównymi zaletami stosowania f-stringów jest to, że są bardziej czytelne, mogą być szybsze i oferują lepszą wydajność:

Źródłowe pandy dla wszystkich: analiza danych w języku Python, Daniel Y. Chen

Benchmarki

Bez wątpienia nowe f-stringssą bardziej czytelne, ponieważ nie musisz zmieniać mapowania ciągów, ale czy jest to szybsze, jak stwierdzono we wspomnianym cytacie?

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

Przeprowadzając 10 milionów testów wydaje się, że nowe f-stringssą faktycznie szybsze w mapowaniu.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.