Python 3.6'da çıktıyı biçimlendirmek için f-dizesinde yeni satır '\ n' nasıl kullanılır?


123

Bu durumu Pythonic yolla f-dizeleriyle nasıl biçimlendireceğimi bilmek istiyorum:

names = ['Adam', 'Bob', 'Cyril']
text = f"Winners are:\n{'\n'.join(names)}"
print(text)

Sorun, bir f-dizesinin ifade bölümlerinde '\'kullanılamamasıdır {...}. Beklenen çıktı:

Winners are:
Adam
Bob
Cyril

11
f"Winners are:\n{chr(10).join(names)}"
wim

Yanıtlar:


135

Yapamazsın. Ters eğik çizgi küme parantezlerinin içinde görünemez {}; bunu yapmak şunla sonuçlanır SyntaxError:

>>> f'{\}'
SyntaxError: f-string expression part cannot include a backslash

Bu, f dizeleri için PEP'de belirtilmiştir :

F dizelerinin ifade bölümlerinde ters eğik çizgiler görünmeyebilir, [...]

Seçeneklerden biri '\n', bir isme atamak ve ardından -string'in .joiniçinde bunu fyapmaktır; yani, birebir kullanmadan:

names = ['Adam', 'Bob', 'Cyril']
nl = '\n'
text = f"Winners are:{nl}{nl.join(names)}"
print(text)

Sonuçlar:

Winners are:
Adam
Bob
Cyril

@Wim tarafından belirtildiği gibi başka bir seçenek, iade chr(10)almak \nve oraya katılmak için kullanmaktır .f"Winners are:\n{chr(10).join(names)}"

Bir başka tabii ki, '\n'.joinönceden ve sonra adı buna göre eklemek:

n = "\n".join(names)
text = f"Winners are:\n{n}"

aynı çıktı ile sonuçlanır.

Not:

Bu, f-stringler ve str.format. İkincisinde, bu anahtarları içeren karşılık gelen tuhaf bir diktenin paketinden çıkarılması durumunda her zaman noktalama işaretini kullanabilirsiniz:

>>> "{\\} {*}".format(**{"\\": 'Hello', "*": 'World!'})
"Hello World!"

(Lütfen bunu yapmayın.)

İlkinde, onları kullanan tanımlayıcılara sahip olamayacağınız için noktalama işaretlerine izin verilmez.


Bir kenara: Diğer cevapların alternatif olarak önerdiği gibi kesinlikle printveya tercih ederim format. Verdiğim seçenekler, sadece herhangi bir nedenle f-dizelerini kullanmanız gerekiyorsa geçerlidir .

Bir şeyin yeni olması, onunla her şeyi denemeniz gerektiği anlamına gelmez ;-)


56

Ayırıcı içeren dizelerin bir listesini yazdırmak için f dizelerine veya diğer biçimlendiricilere ihtiyacınız yoktur. Sadece kullanmak sepkelime argüman için print():

names = ['Adam', 'Bob', 'Cyril']
print('Winners are:', *names, sep='\n')

Çıktı:

Winners are:
Adam
Bob
Cyril

Bununla birlikte, str.join()/str.format() here kullanımı, herhangi bir f-string geçici çözümünden muhtemelen daha basit ve daha okunaklı olacaktır:

print('\n'.join(['Winners are:', *names]))
print('Winners are:\n{}'.format('\n'.join(names)))

13
Şimdiye kadarki en iyi cevap. Bu günlerde bir nesnenin içine bakmak için her zaman yazdırma işlevinde yıldız paketini açmayı kullanıyorum, örneğin print(*dir(some_object), sep='\n')veya print(*vars(some_object), sep='\n').
Rick Monica'yı

1
Listeyi doğrudan yazdırmak istemiyorsanız, örneğin bir kaydediciye iletiyorsanız ne yaparsınız?
bob

1
@bob: o zaman sadece kullanmak str.join(): text = '\n'.join(['Winners are:', *names]). BTW, herhangi bir dosyayaprint() yazmak için kullanılabilir ( varsayılan olarak bağımsız değişkenle belirtilir ). filesys.stdout
Eugene Yarmash

11

Başkalarının söylediği gibi ters eğik çizgileri f dizelerinde kullanamazsınız, ancak bunu kullanarak adım atabilirsiniz os.linesep(bunun \ntüm platformlarda olmayacağını ve ikili dosyaları okumadıkça / yazmadıkça önerilmez; Rick'in yorumlarına bakın):

>>> import os
>>> names = ['Adam', 'Bob', 'Cyril']
>>> print(f"Winners are:\n{os.linesep.join(names)}")
Winners are:
Adam
Bob
Cyril 

Ya da belki daha az okunabilir şekilde, fakat olması garanti \nile chr():

>>> print(f"Winners are:\n{chr(10).join(names)}")
Winners are:
Adam
Bob
Cyril

2
Ben değildim, ama kullanan os.linesepbir iyi bir fikir değil metin yazarken.
Rick Monica'yı

1
@RickTeachey Uyarıyı zaten parantez içinde ekledim ve alternatif bir yaklaşım önerdim. Her neyse, OP metin modunda açılan bir dosyaya yazmıyor, ekrana yazdırıyor
Chris_Rands

Bunun önemli olduğunu sanmıyorum. os.linesepsadece ikili modda okumak veya okumak ve yazmak içindir . Bu durumda da aynı şekilde çalışacağını biliyorum, ama başlamak kötü bir alışkanlık. Ama yine: Olumsuz oy değildim. Uyarı benim için yeterince iyi. :)
Rick Monica'yı destekliyor

7

Diğer cevaplar, satırsonu karakterinin bir f-string alanına nasıl yerleştirileceğine dair fikir verir. Bununla birlikte, OP'nin verdiği örnek için (ki bu, OP'nin fiili kullanım durumunun göstergesi olabilir veya olmayabilir), bu fikirlerin hiçbirinin gerçekten kullanılmaması gerektiğini iddia ediyorum.

F dizelerini kullanmanın tüm amacı kod okunabilirliğini arttırmaktır. F dizeleriyle yapamayacağınız hiçbir şey yoktur format. Bununla ilgili daha okunabilir bir şey olup olmadığını dikkatlice düşünün (eğer yapabilirseniz):

f"Winners are:\n{'\n'.join(names)}"

...veya bu:

newline = '\n'
f"Winners are:\n{newline.join(names)}"

...veya bu:

"Winners are:\n{chr(10).join(names)}"

buna kıyasla:

"Winners are:\n{}".format('\n'.join(names))

Son yol, daha fazla değilse de en azından o kadar okunabilir.

Kısacası: sadece parlak bir tornavidaya sahip olduğunuz için tornavidaya ihtiyacınız olduğunda çekiç kullanmayın. Kod yazıldığından çok daha sık okunur.

Diğer kullanım durumları için, evet, chr(10)fikir veya newlinefikir uygun olabilir. Ama verilen için değil.


7
Okunabilirlik özneldir :) ... eski uygulama yetenekli kişilere uygundur ve bazı durumlarda daha okunabilir olabilir, ancak acemiler tarafından neredeyse bilinmeyebilir ve bu nedenle onlar için okunamaz olabilir. Felsefi bakış açısı için özür dilerim.
malmed

2
@malmed Okunabilirlik genellikle öznel değildir. Bu durumda kesinlikle değil. Ancak uzun uzun tartışmaya değmez.
Rick Monica'ya

1
@malmed Okunabilirliğin önceki deneyimlerle eğitilebilmesi anlamında "öznel" olduğu konusunda haklısınız . Ancak beyinlerimizin ve duyularımızın sınırlamaları olduğu için okunabilirlik, ilgili metni taramanın fiziksel olarak ne kadar kolay olduğu, insan beyninin onu ne sıklıkla doğru model eşleştirme eğiliminde olduğu, diğerleriyle ilgili beyin tahminlerimize ne kadar doğru işaret ettiği açısından objektif olarak ölçülebilir. kod (sonun ne olacağına dair ipucu veren bir ifadenin / satırın başlangıcı dahil) ve bir acemi için ne kadar kolay okunabilir hale geldiği.
mtraceur
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.