Utilisation du formatage de chaînes Python avec des listes


112

Je construis une chaîne sen Python 2.6.5 qui aura un nombre variable de %sjetons, qui correspondent au nombre d'entrées dans la liste x. J'ai besoin d'écrire une chaîne formatée. Ce qui suit ne fonctionne pas, mais indique ce que j'essaie de faire. Dans cet exemple, il y a trois %sjetons et la liste a trois entrées.

s = '%s BLAH %s FOO %s BAR'
x = ['1', '2', '3']
print s % (x)

Je voudrais que la chaîne de sortie soit:

1 BLAH 2 FOO 3 BAR

Réponses:


112
print s % tuple(x)

au lieu de

print s % (x)

5
(x)est la même chose que x. Mettre un seul jeton entre crochets n'a aucune signification en Python. Vous mettez généralement des crochets foo = (bar, )pour faciliter la lecture, mais vous faites foo = bar,exactement la même chose.
patrys le

11
print s % (x)est ce qu'OP a écrit, je le citais juste.
infrarouge du

J'étais juste en train de fournir un conseil linguistique, pas de critiquer votre réponse (en fait, je l'ai +1). Vous n'avez pas écrit non foo = (bar, )plus :)
patrys

2
J'utilise la (x)notation pour plus de clarté; cela évite également d'oublier les crochets si vous ajoutez ultérieurement des variables supplémentaires.
SabreWolfy

Et si vous souhaitez rechercher vos variables à partir de plusieurs listes? tuple ne prend qu'une seule liste, et le formateur semble ne prendre qu'un seul tuple
errant.info

150

Vous devriez jeter un oeil à la méthode de format de python. Vous pouvez ensuite définir votre chaîne de mise en forme comme ceci:

>>> s = '{0} BLAH BLAH {1} BLAH {2} BLAH BLIH BLEH'
>>> x = ['1', '2', '3']
>>> print s.format(*x)
'1 BLAH BLAH 2 BLAH 3 BLAH BLIH BLEH'

1
Le problème de l'OP n'est pas la méthode mais le format des paramètres. %l'opérateur ne décompresse que les tuples.
patrys le

Cela rendrait la construction splus complexe, car je devrais inclure des nombres incrémentiels plutôt que simplement %spour chaque position. sest construit en un certain nombre d'étapes différentes, il est donc beaucoup plus facile d'inclure simplement le %sjeton.
SabreWolfy le

2
@SabreWolfy Si vous construisez il precedurally alors vous pourriez trouver plus facile de nommer vos espaces réservés et utiliser un dict pour mettre en forme la chaîne résultante: print u'%(blah)d BLAHS %(foo)d FOOS …' % {'blah': 15, 'foo': 4}.
patrys

2
@SabreWolfy: Dans Python 2.7, vous pouvez omettre les numéros de champ:s = '{} BLAH {} BLAH BLAH {} BLAH BLAH BLAH'
pause jusqu'à nouvel ordre.

Cette réponse est potentiellement déroutante, car elle donne l'impression que les valeurs numériques de 0, 1 et 2 sont en quelque sorte liées au nombre de fois où le mot «BLAH» apparaît.
SabreWolfy le

31

Suite à cette page de ressources , si la longueur de x varie, nous pouvons utiliser:

', '.join(['%.2f']*len(x))

pour créer un espace réservé pour chaque élément de la liste x. Voici l'exemple:

x = [1/3.0, 1/6.0, 0.678]
s = ("elements in the list are ["+', '.join(['%.2f']*len(x))+"]") % tuple(x)
print s
>>> elements in the list are [0.33, 0.17, 0.68]

1
Le lien est maintenant mort.
MK Hunter

19

Voici une seule ligne. Une petite réponse improvisée utilisant le format avec print () pour parcourir une liste.

Que diriez-vous de cela (python 3.x):

sample_list = ['cat', 'dog', 'bunny', 'pig']
print("Your list of animals are: {}, {}, {} and {}".format(*sample_list))

Lisez les documents ici sur l'utilisation de format () .


18

Depuis que je viens d'apprendre ce truc cool (indexation dans des listes à partir d'une chaîne de format), j'ajoute à cette vieille question.

s = '{x[0]} BLAH {x[1]} FOO {x[2]} BAR'
x = ['1', '2', '3']
print (s.format (x=x))

Production:

1 BLAH 2 FOO 3 BAR

Cependant, je n'ai toujours pas compris comment faire du découpage (à l'intérieur de la chaîne de format '"{x[2:4]}".format...) et j'aimerais bien le savoir si quelqu'un a une idée, mais je soupçonne que vous ne pouvez tout simplement pas le faire.


Je suis un peu curieux de connaître votre cas d'utilisation du tranchage.
Michael

1
Je n'en ai pas vraiment un ... je pense que je pensais juste que ce serait chouette de pouvoir le faire
Joran Beasley

11

C'était une question amusante! Une autre façon de gérer cela pour les listes de longueur variable est de créer une fonction qui tire pleinement parti de la .formatméthode et du déballage des listes. Dans l'exemple suivant, je n'utilise aucun formatage sophistiqué, mais cela peut facilement être modifié pour répondre à vos besoins.

list_1 = [1,2,3,4,5,6]
list_2 = [1,2,3,4,5,6,7,8]

# Create a function that can apply formatting to lists of any length:
def ListToFormattedString(alist):
    # Create a format spec for each item in the input `alist`.
    # E.g., each item will be right-adjusted, field width=3.
    format_list = ['{:>3}' for item in alist] 

    # Now join the format specs into a single string:
    # E.g., '{:>3}, {:>3}, {:>3}' if the input list has 3 items.
    s = ','.join(format_list)

    # Now unpack the input list `alist` into the format string. Done!
    return s.format(*alist)

# Example output:
>>>ListToFormattedString(list_1)
'  1,  2,  3,  4,  5,  6'
>>>ListToFormattedString(list_2)
'  1,  2,  3,  4,  5,  6,  7,  8'

3

La même chose que la réponse de @ neobot mais un peu plus moderne et succincte.

>>> l = range(5)
>>> " & ".join(["{}"]*len(l)).format(*l)
'0 & 1 & 2 & 3 & 4'

0
x = ['1', '2', '3']
s = f"{x[0]} BLAH {x[1]} FOO {x[2]} BAR"
print(s)

La sortie est

1 BLAH 2 FOO 3 BAR
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.