Insertion de la même valeur plusieurs fois lors du formatage d'une chaîne

111

J'ai une chaîne de cette forme

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

Tous les% s de la chaîne ont la même valeur (ie s). Y a-t-il une meilleure façon d'écrire cela? (Plutôt que de lister trois fois)

Goutham
la source
2
Cet %opérateur de chaîne sera "obsolète sur Python 3.1 et supprimé plus tard à un moment donné" docs.python.org/release/3.0.1/whatsnew/ ... maintenant je me demande quel est le moyen le plus conseillé pour la compatibilité de version et la sécurité.
cregox
2
@Cawas Je sais que c'est assez tard, mais j'aime utiliser str.format(). Ex .: query = "SELECT * FROM {named_arg}"; query.format(**kwargs), où queryest la chaîne de format et kwargsest un dictionnaire avec des clés correspondant au named_args dans la chaîne de format.
Edwin
4
@Cawas Ouais, sauf Adam utilisé la notation tuple, où {0}, {1}, {2}etc. correspondent aux indices de tuples 0, 1, et 2, respectivement. Alternativement, il est également possible de nommer les arguments (comme {named_arg}) et de définir chacun dans la méthode de format, comme ceci:'Hi {fname} {lname}!'.format(fname='John', lname='Doe')
Edwin
2
@bignose Vous avez marqué les deux questions en double, c'est comme google.com
...

Réponses:

203

Vous pouvez utiliser le formatage de chaîne avancé , disponible dans Python 2.6 et Python 3.x:

incoming = 'arbit'
result = '{0} hello world {0} hello world {0}'.format(incoming)
Adam Rosenfield
la source
11
~ Ma préférence personnelle, optez pour le style result = '{st} hello world {st} hello world {st}'.format(st=incoming)
kwargs
40
incoming = 'arbit'
result = '%(s)s hello world %(s)s hello world %(s)s' % {'s': incoming}

Vous voudrez peut-être lire ceci pour comprendre: Opérations de formatage de chaîne .

mhawke
la source
1
Agréable. J'avais oublié cela. les locaux () feront également l'affaire.
Goutham
2
@Goutham: La réponse d'Adam Rosenfield pourrait être meilleure si votre version de Python est à jour.
mhawke
C'est en fait. Je suis toujours en train de m'habituer aux nouvelles opérations de formatage de chaîne.
Goutham
3
encore mieux, vous pouvez multiplier la chaîne de base: '% (s) s hello world' * 3% {'s': 'asdad'}
dalloliogm
15

Vous pouvez utiliser le type de formatage du dictionnaire:

s='arbit'
string='%(key)s hello world %(key)s hello world %(key)s' % {'key': s,}
Lucas S.
la source
1
Semble être très peu utile de fournir cette réponse en double. En voici un autre: '% (string_goes_here) s bonjour le monde% (string_goes_here) s bonjour le monde% (string_goes_here) s'% {'string_goes_here': s,}. Il y a pratiquement un nombre infini de possibilités.
mhawke
3
mhawke: j'ai posté le message avant que mon navigateur ne recharge la page, donc je ne savais pas à ce moment-là que la question avait déjà été répondue. Vous n'avez pas besoin d'être un homme impoli !!.
Lucas S.
2
@Lucas: Je suppose qu'il est possible qu'il vous ait fallu 13 minutes pour taper votre réponse :) et merci pour le vote négatif ... très apprécié.
mhawke
13

Cela dépend de ce que vous entendez par mieux. Cela fonctionne si votre objectif est la suppression de la redondance.

s='foo'
string='%s bar baz %s bar baz %s bar baz' % (3*(s,))
jjames
la source
3
>>> s1 ='arbit'
>>> s2 = 'hello world '.join( [s]*3 )
>>> print s2
arbit hello world arbit hello world arbit
Whiterocker
la source
Je suppose que l'exemple de la question ne concernait pas la répétition de «bonjour le monde», mais un vrai modèle sans duplication. C'est pourquoi j'ai voté contre.
Gra
1

Fstrings

Si vous utilisez, Python 3.6+vous pouvez utiliser le nouveau soi-disant f-stringsqui signifie chaînes formatées et il peut être utilisé en ajoutant le caractère fau début d'une chaîne pour l'identifier comme une chaîne f .

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!

Les principaux avantages de l'utilisation des chaînes f sont qu'elles sont plus lisibles, peuvent être plus rapides et offrent de meilleures performances:

Source Pandas pour tous: analyse des données Python, par Daniel Y. Chen

Benchmarks

Nul doute que les nouveaux f-stringssont plus lisibles, car vous n'avez pas à remapper les chaînes, mais est-ce plus rapide, comme indiqué dans la citation susmentionnée?

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

En exécutant 10 millions de tests, il semble que les nouveaux f-stringssont en fait plus rapides dans la cartographie.

user1767754
la source