Làm cách nào để sử dụng dòng mới '\ n' trong f-string để định dạng đầu ra trong Python 3.6?


109

Tôi muốn biết cách định dạng trường hợp này theo cách Pythonic với f-string:

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

Vấn đề là nó '\'không thể được sử dụng bên trong các {...}phần biểu thức của một chuỗi f. Sản lượng mong đợi:

Winners are:
Adam
Bob
Cyril

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

Câu trả lời:


123

Bạn không thể. Dấu gạch chéo ngược không được xuất hiện bên trong dấu ngoặc nhọn {}; làm như vậy dẫn đến SyntaxError:

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

Điều này được chỉ định trong PEP cho f-string:

Dấu gạch chéo ngược có thể không xuất hiện bên trong các phần biểu thức của chuỗi f, [...]

Một tùy chọn là giả '\n'định một tên và sau đó đặt tên đó .joinbên trong f-string; nghĩa là, không sử dụng một chữ:

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

Kết quả trong:

Winners are:
Adam
Bob
Cyril

Một tùy chọn khác, như được chỉ định bởi @wim, là sử dụng chr(10)để được \ntrả lại và sau đó tham gia ở đó.f"Winners are:\n{chr(10).join(names)}"

Tuy nhiên, một cách khác, tất nhiên, là đặt '\n'.jointrước và sau đó thêm tên cho phù hợp:

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

mà kết quả là cùng một đầu ra.

Ghi chú:

Đây là một trong những khác biệt nhỏ giữa f-strings và str.format. Trong phần sau, bạn luôn có thể sử dụng dấu câu được cấp để giải nén một câu lệnh lập dị tương ứng có chứa các khóa đó:

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

(Vui lòng không làm điều này.)

Trước đây, dấu chấm câu không được phép vì bạn không thể có số nhận dạng sử dụng chúng.


Ngoài ra: Tôi chắc chắn sẽ chọn printhoặc format, như các câu trả lời khác đề xuất như một sự thay thế. Các tùy chọn tôi đã đưa ra chỉ áp dụng nếu vì lý do nào đó bạn phải sử dụng chuỗi f.

Chỉ vì một cái gì đó mới, không có nghĩa là bạn nên thử và làm mọi thứ với nó ;-)


55

Bạn không cần f-string hoặc các định dạng khác để in danh sách các chuỗi có dấu phân tách. Chỉ cần sử dụng sepđối số từ khóa để print():

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

Đầu ra:

Winners are:
Adam
Bob
Cyril

Điều đó nói rằng, việc sử dụng str.join()/str.format() here được cho là đơn giản hơn và dễ đọc hơn bất kỳ giải pháp thay thế f-string nào:

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

13
Câu trả lời tốt nhất cho đến nay. Tôi thường xuyên sử dụng chức năng giải nén dấu sao trong chức năng in những ngày này để xem bên trong một số đối tượng, ví dụ: print(*dir(some_object), sep='\n')hoặc print(*vars(some_object), sep='\n').
Rick ủng hộ Monica

1
Bạn phải làm gì nếu bạn không muốn in danh sách trực tiếp, ví dụ như nếu bạn đang chuyển nó đến một trình ghi nhật ký?
bob

1
@ Bob: sau đó chỉ cần sử dụng str.join(): text = '\n'.join(['Winners are:', *names]). BTW, print()có thể được sử dụng để ghi vào bất kỳ tệp nào (được chỉ định với fileđối số, sys.stdouttheo mặc định).
Eugene Yarmash

10

Bạn không thể sử dụng dấu gạch chéo ngược trong chuỗi f như những người khác đã nói, nhưng bạn có thể giải quyết vấn đề này bằng cách sử dụng os.linesep(mặc dù lưu ý rằng điều này sẽ không có \ntrên tất cả các nền tảng và không được khuyến nghị trừ khi đọc / ghi tệp nhị phân; xem nhận xét của Rick ):

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

Hoặc có thể theo cách ít đọc hơn, nhưng được đảm bảo \n, với chr():

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

2
Không phải là tôi, nhưng sử dụng os.linesepkhông phải là một ý tưởng tốt khi viết văn bản.
Rick ủng hộ Monica

1
@RickTeachey Tôi đã thêm thông báo trước trong ngoặc đơn và đề xuất một cách tiếp cận thay thế. Dù sao, OP được in vào màn hình, không viết vào một tập tin đã mở trong chế độ văn bản
Chris_Rands

Tôi không nghĩ nó quan trọng. os.linesepchỉ để đọc hoặc đọc và ghi ở chế độ nhị phân . Tôi biết nó sẽ hoạt động tương tự trong trường hợp này, nhưng đó là một thói quen xấu khi bắt đầu. Nhưng một lần nữa: Tôi không phải là người phản đối. Lời báo trước là đủ tốt cho tôi. :)
Rick hỗ trợ Monica

6

Các câu trả lời khác cung cấp ý tưởng về cách đặt ký tự dòng mới vào trường f-string. Tuy nhiên, tôi lập luận rằng đối với ví dụ mà OP đưa ra (có thể có hoặc có thể không chỉ ra trường hợp sử dụng thực tế của OP), không nên sử dụng ý tưởng nào trong số này.

Toàn bộ điểm của việc sử dụng chuỗi f là tăng khả năng đọc mã. Bạn không thể làm gì với chuỗi f mà bạn không thể làm được format. Hãy xem xét cẩn thận xem có điều gì có thể đọc thêm về điều này không (nếu bạn có thể làm điều đó):

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

... hoặc cái này:

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

... hoặc cái này:

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

so với cái này:

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

Cách cuối cùng ít nhất là có thể đọc được, nếu không muốn nói là hơn thế.

Tóm lại: đừng dùng búa khi bạn cần một cái tuốc nơ vít chỉ vì bạn có một cái mới sáng bóng. Mã được đọc thường xuyên hơn nó được viết.

Đối với các trường hợp sử dụng khác, có, có thể chr(10)ý tưởng hoặc newlineý tưởng có thể phù hợp. Nhưng không phải cho một trong những cho.


7
Khả năng đọc là chủ quan :) ... thực hành cũ phù hợp với những người có kỹ năng và có thể dễ đọc hơn trong một số trường hợp, nhưng có thể hầu như không biết đối với những người không có kinh nghiệm và do đó không thể đọc được đối với họ. Xin lỗi vì quan điểm triết học.
malmed

2
@malmed Khả năng đọc nói chung không phải là chủ quan. Chắc chắn không phải trong trường hợp này. Nhưng nó không đáng để tranh cãi về độ dài.
Rick ủng hộ Monica.

@malmed Bạn nói đúng rằng khả năng đọc là "chủ quan" theo nghĩa là nó có thể đào tạo được bằng kinh nghiệm trước đó. Nhưng bởi vì não bộ và các giác quan của chúng ta có những giới hạn, khả năng đọc có thể được đo lường một cách khách quan về mức độ dễ dàng về mặt vật lý để quét văn bản liên quan, tần suất bộ não của con người có xu hướng khớp với nó một cách chính xác, nó gợi ý cho bộ não của chúng ta những dự đoán về những thứ khác một cách chính xác như thế nào. mã (bao gồm phần đầu của một câu lệnh / dòng gợi ý về phần cuối sẽ như thế nào) và nó trở nên dễ đọc hơn đối với người mới sử dụng.
mtraceur
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.