Używanie formatowania ciągów w języku Python z listami


112

sW Pythonie 2.6.5 konstruuję ciąg znaków, który będzie miał różną liczbę %stokenów, odpowiadających liczbie wpisów na liście x. Muszę napisać sformatowany ciąg. Poniższe informacje nie działają, ale wskazują, co próbuję zrobić. W tym przykładzie są trzy %stokeny, a lista ma trzy wpisy.

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

Chciałbym, aby ciąg wyjściowy był następujący:

1 BLAH 2 FOO 3 BAR

Odpowiedzi:


112
print s % tuple(x)

zamiast

print s % (x)

5
(x)to to samo co x. Umieszczenie pojedynczego tokena w nawiasach nie ma znaczenia w Pythonie. Zwykle umieszczasz nawiasy, foo = (bar, )aby ułatwić czytanie, ale robisz foo = bar,dokładnie to samo.
patrys

11
print s % (x)tak napisał OP, właśnie cytuję go / ją.
podczerwień,

Dałem tylko wskazówkę językową, a nie krytykę odpowiedzi (w rzeczywistości dałem jej +1). Ty też nie napisałeś foo = (bar, ):)
patrys

2
Używam (x)notacji dla jasności; unika również zapominania o nawiasach, jeśli później dodasz dodatkowe zmienne.
SabreWolfy,

A co jeśli chcesz pozyskiwać zmienne z wielu list? krotka zajmuje tylko jedną listę, a program formatujący wydaje się pobierać tylko jedną krotkę
errant.info

150

Powinieneś rzucić okiem na metodę formatowania w Pythonie. Następnie możesz zdefiniować ciąg formatujący w następujący sposób:

>>> 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
Problem PO nie polega na metodzie, ale na formacie parametrów. %operator tylko rozpakowuje krotki.
patrys

To sprawiłoby, że konstrukcja byłaby sbardziej złożona, ponieważ musiałbym uwzględnić rosnące liczby, a nie tylko %sdla każdej pozycji. sskłada się z wielu różnych etapów, więc o wiele łatwiej jest po prostu dołączyć %stoken.
SabreWolfy,

2
@SabreWolfy Jeśli skonstruować go precedurally wtedy może się okazać, że łatwiej wymienić swoje zastępcze i użyć dict sformatować ciąg wynikowy: print u'%(blah)d BLAHS %(foo)d FOOS …' % {'blah': 15, 'foo': 4}.
patrys

2
@SabreWolfy: W Pythonie 2.7 możesz pominąć numery pól:s = '{} BLAH {} BLAH BLAH {} BLAH BLAH BLAH'
Wstrzymano do odwołania.

Ta odpowiedź jest potencjalnie myląca, ponieważ sprawia, że ​​wygląda na to, że wartości liczbowe 0, 1 i 2 są w jakiś sposób powiązane z tym, ile razy pojawia się słowo „BLAH”.
SabreWolfy

31

Po tej stronie zasobów , jeśli długość x jest różna, możemy użyć:

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

aby utworzyć uchwyt zastępczy dla każdego elementu z listy x. Oto przykład:

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
Link jest teraz martwy.
MK Hunter

19

Oto jedna wkładka. Mała prowizoryczna odpowiedź wykorzystująca format z print () do iteracji listy.

Co powiesz na to (python 3.x):

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

Przeczytaj dokumentację dotyczącą używania format () .


18

Ponieważ właśnie dowiedziałem się o tej fajnej rzeczy (indeksowanie do list z ciągu formatu), dodaję do tego starego pytania.

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

Wynik:

1 BLAH 2 FOO 3 BAR

Jednak nadal nie wymyśliłem, jak zrobić cięcie (wewnątrz ciągu formatującego '"{x[2:4]}".format...) i chciałbym to rozgryźć, jeśli ktoś ma pomysł, jednak podejrzewam, że po prostu nie możesz tego zrobić.


Jestem trochę ciekawy twojego przypadku użycia do krojenia.
Michael

1
tak naprawdę nie mam ... myślę, że po prostu pomyślałem, że byłoby fajnie móc to zrobić
Joran Beasley

11

To było zabawne pytanie! Innym sposobem rozwiązania tego problemu w przypadku list o zmiennej długości jest zbudowanie funkcji, która w pełni korzysta z .formatmetody i rozpakowywania list. W poniższym przykładzie nie używam żadnego wymyślnego formatowania, ale można je łatwo zmienić w zależności od potrzeb.

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

To samo, co odpowiedź @ neobot, ale trochę bardziej nowoczesne i zwięzłe.

>>> 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)

Wynik jest

1 BLAH 2 FOO 3 BAR
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.