Định dạng chuỗi đầu ra, căn lề phải


148

Tôi đang xử lý tệp văn bản chứa tọa độ x, y, z

     1      128  1298039
123388        0        2
....

mỗi dòng được phân định thành 3 mục bằng cách sử dụng

words = line.split()

Sau khi xử lý dữ liệu, tôi cần ghi lại tọa độ trong một tệp txt khác để các mục trong mỗi cột được căn chỉnh đúng (cũng như tệp đầu vào). Mỗi dòng bao gồm các tọa độ

line_new = words[0]  + '  ' + words[1]  + '  ' words[2].

Có bất kỳ trình thao tác nào như std::setw()vv trong C ++ cho phép đặt chiều rộng và căn chỉnh không?

Câu trả lời:


229

Hãy thử phương pháp này bằng str.formatcú pháp mới hơn :

line_new = '{:>12}  {:>12}  {:>12}'.format(word[0], word[1], word[2])

Và đây là cách thực hiện bằng %cú pháp cũ (hữu ích cho các phiên bản Python cũ không hỗ trợ str.format):

line_new = '%12s  %12s  %12s' % (word[0], word[1], word[2])

39
Lưu ý cách cú pháp "cũ" sạch hơn, dễ đọc hơn và ngắn hơn.
fyngyrz

2
Tôi nghĩ rằng tôi muốn thêm một liên kết trực tiếp hơn so với một điều kiện: docs.python.org/2/library/...
brw59

47
Nói ngắn gọn hơn, tôi không biết ý nghĩa thực sự của trình dọn dẹp là gì, nhưng 'dễ đọc hơn' chỉ vì nó quen thuộc, tôi nghĩ vậy. Nếu bạn chưa quen với một trong số chúng, định dạng mới có vẻ dễ đọc hơn. ".format" để định dạng chuỗi chắc chắn có vẻ trực quan hơn so với tỷ lệ phần trăm / modulo. Mũi tên phải để căn phải cũng có vẻ khá trực quan.
Đánh dấu

2
@Mark Một cách mà cách cũ sạch hơn là sử dụng ít ký tự hơn. Có với sự quen thuộc, cách mới trở nên trực quan nhưng nó không sạch sẽ và đơn giản hơn. Cách cũ trực quan hơn cho những người đã quen với cú pháp đến với chúng ta thông qua ngôn ngữ C đáng kính, một ngôn ngữ của sự ngắn gọn và chính xác mẫu mực. Tiền lệ nào cho cách mới?
Stephen Boston

2
@StephenBoston Tôi sẽ để các chuyên gia dễ đọc, nhưng cách mới hoàn toàn sạch sẽ hơn. Parens không còn là tùy chọn. % có thể bị nhầm lẫn với một toán tử toán học (mặc dù, không có khả năng trong ngữ cảnh, nhưng trong nháy mắt chắc chắn). Cách cũ sẽ thất bại nếu từ [n] không thuộc loại dự kiến ​​(chuỗi trong trường hợp này). Cách mới không cần biết loại đến là gì, nó luôn hoạt động. Sạch sẽ và đơn giản. Công bằng mà nói, tôi không bao giờ thấy thoải mái với phong cách printf (tôi chủ yếu làm C với cout).
Zim

53

Nó có thể đạt được bằng cách sử dụng rjust:

line_new = word[0].rjust(10) + word[1].rjust(10) + word[2].rjust(10)

51

Bạn có thể căn chỉnh nó như thế:

print('{:>8} {:>8} {:>8}'.format(*words))

trong đó >có nghĩa là " căn lề phải " và 8chiều rộng cho giá trị cụ thể.

Và đây là một bằng chứng:

>>> for line in [[1, 128, 1298039], [123388, 0, 2]]:
    print('{:>8} {:>8} {:>8}'.format(*line))


       1      128  1298039
  123388        0        2

Thi thiên *linecó nghĩa là linedanh sách sẽ được giải nén, do đó .format(*line)hoạt động tương tự .format(line[0], line[1], line[2])(giả sử linelà một danh sách chỉ có ba yếu tố).



18

Đây là một cách khác để bạn có thể định dạng bằng định dạng 'f-string':

print(
    f"{'Trades:':<15}{cnt:>10}",
    f"\n{'Wins:':<15}{wins:>10}",
    f"\n{'Losses:':<15}{losses:>10}",
    f"\n{'Breakeven:':<15}{evens:>10}",
    f"\n{'Win/Loss Ratio:':<15}{win_r:>10}",
    f"\n{'Mean Win:':<15}{mean_w:>10}",
    f"\n{'Mean Loss:':<15}{mean_l:>10}",
    f"\n{'Mean:':<15}{mean_trd:>10}",
    f"\n{'Std Dev:':<15}{sd:>10}",
    f"\n{'Max Loss:':<15}{max_l:>10}",
    f"\n{'Max Win:':<15}{max_w:>10}",
    f"\n{'Sharpe Ratio:':<15}{sharpe_r:>10}",
)

Điều này sẽ cung cấp đầu ra sau đây:

Trades:              2304
Wins:                1232
Losses:              1035
Breakeven:             37
Win/Loss Ratio:      1.19
Mean Win:           0.381
Mean Loss:         -0.395
Mean:               0.026
Std Dev:             0.56
Max Loss:          -3.406
Max Win:             4.09
Sharpe Ratio:      0.7395

Những gì bạn đang làm ở đây là bạn đang nói rằng cột đầu tiên dài 15 ký tự và nó còn lại hợp lý và cột thứ hai (các giá trị) dài 10 ký tự và nó hợp lý.


Có cách nào để tối ưu hóa độ rộng của các định dạng không? Trong ví dụ này nếu bạn quyết định thay đổi định dạng thành 20 và 15 chiều rộng, nó yêu cầu thay đổi nhiều dòng. widths = [15, 10] f"{'Trades:':<width[0]}{cnt:>width[1]}",Tôi muốn đạt được sth như trên.
Tomasz Sabała

1
Hiểu rồi! Có lẽ ai đó sẽ thấy nó hữu ích. Tôi cần thêm một dấu ngoặc lồng cho việc này vì vậy:f"{'Trades:':<{width[0]}}{cnt:>{width[1]}}"
Tomasz Sabała

1
Đôi khi, những câu trả lời hay nhất là những câu trả lời không trả lời chính xác. Cảm ơn vì điều đó! :)
Brian Wiley

5

Lập bảng đơn giản của đầu ra:

a = 0.3333333
b = 200/3
print("variable a    variable b")
print("%10.2f    %10.2f" % (a, b))

đầu ra:

variable a    variable b
      0.33         66.67

% 10.2f: 10 là độ dài tối thiểu và 2 là số vị trí thập phân.


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.