Làm thế nào để in một chuỗi theo chiều rộng cố định?


103

Tôi có mã này (in sự xuất hiện của tất cả các hoán vị trong một chuỗi)

def splitter(str):
    for i in range(1, len(str)):
        start = str[0:i]
        end = str[i:]
        yield (start, end)
        for split in splitter(end):
            result = [start]
            result.extend(split)
            yield result    

el =[];

string = "abcd"
for b in splitter("abcd"):
    el.extend(b);

unique =  sorted(set(el));

for prefix in unique:
    if prefix != "":
        print "value  " , prefix  , "- num of occurrences =   " , string.count(str(prefix));

Tôi muốn in tất cả các trường hợp hoán vị có trong chuỗi có thể thay thế được.

vì hoán vị không có cùng chiều dài nên tôi muốn sửa chiều rộng và in nó theo kiểu đẹp không giống như thế này:

value   a - num of occurrences =    1
value   ab - num of occurrences =    1
value   abc - num of occurrences =    1
value   b - num of occurrences =    1
value   bc - num of occurrences =    1
value   bcd - num of occurrences =    1
value   c - num of occurrences =    1
value   cd - num of occurrences =    1
value   d - num of occurrences =    1

Làm thế nào tôi có thể sử dụng formatđể làm điều đó?

Tôi đã tìm thấy những bài đăng này nhưng nó không hoạt động tốt với các chuỗi chữ và số:

định dạng chuỗi python chiều rộng cố định

Đặt độ dài cố định bằng python


1
Còn về print '% 10s'% 'mystring'
TJD 9/12/11

2
Ngạc nhiên rằng "\t"không được liệt kê như một tùy chọn trong bất kỳ giải pháp nào.

Câu trả lời:


112

EDIT 2013-12-11 - Câu trả lời này rất cũ. Nó vẫn hợp lệ và chính xác, nhưng những người nhìn vào điều này nên thích cú pháp định dạng mới hơn .

Bạn có thể sử dụng định dạng chuỗi như sau:

>>> print '%5s' % 'aa'
   aa
>>> print '%5s' % 'aaa'
  aaa
>>> print '%5s' % 'aaaa'
 aaaa
>>> print '%5s' % 'aaaaa'
aaaaa

Về cơ bản:

  • các %thông báo cho nhân vật python nó sẽ phải thay thế một cái gì đó để một mã thông báo
  • các sthông báo cho nhân vật python token sẽ là một chuỗi
  • các 5(hoặc bất kỳ số nào bạn muốn) thông báo python để pad chuỗi với không gian lên đến 5 ký tự.

Trong trường hợp cụ thể của bạn, cách triển khai khả thi có thể trông giống như sau:

>>> dict_ = {'a': 1, 'ab': 1, 'abc': 1}
>>> for item in dict_.items():
...     print 'value %3s - num of occurances = %d' % item # %d is the token of integers
... 
value   a - num of occurances = 1
value  ab - num of occurances = 1
value abc - num of occurances = 1

LƯU Ý PHỤ: Chỉ tự hỏi liệu bạn có biết về sự tồn tại của itertoolsmô-đun hay không . Ví dụ: bạn có thể lấy danh sách tất cả các kết hợp của mình trong một dòng với:

>>> [''.join(perm) for i in range(1, len(s)) for perm in it.permutations(s, i)]
['a', 'b', 'c', 'd', 'ab', 'ac', 'ad', 'ba', 'bc', 'bd', 'ca', 'cb', 'cd', 'da', 'db', 'dc', 'abc', 'abd', 'acb', 'acd', 'adb', 'adc', 'bac', 'bad', 'bca', 'bcd', 'bda', 'bdc', 'cab', 'cad', 'cba', 'cbd', 'cda', 'cdb', 'dab', 'dac', 'dba', 'dbc', 'dca', 'dcb']

và bạn có thể nhận được số lần xuất hiện bằng cách sử dụng combinationskết hợp với count().


24
Bạn có lẽ nên đề cập rằng các số âm cung cấp đầu ra được đệm căn trái; điều này hầu như không trực quan cho người mới bắt đầu.
tripleee

+1 cho @tripleee, nếu không có số âm của bạn đưa ra nhận xét hợp lý bên trái, tôi sẽ đánh đầu lâu hơn ... thx m8.
Briford Wylie

Điều này trực quan và ngắn gọn hơn nhiều so với str.format mới. Tôi không hiểu tại sao có push này trong python hướng chập
scottmrogowski

Có cách nào để điền vào các khoảng trống với một ký tự cụ thể? Ví dụ, nếu chúng ta cần in "05" thay vì "5"
Harshit Jindal

1
Dưới đây là một số thủ thuật khác để in chiều rộng cố định thanh lịch với f-string trên Medium .
pfabri

197

Tôi thấy sử dụng str.formatthanh lịch hơn nhiều:

>>> '{0: <5}'.format('ss')
'ss   '
>>> '{0: <5}'.format('sss')
'sss  '
>>> '{0: <5}'.format('ssss')
'ssss '
>>> '{0: <5}'.format('sssss')
'sssss'

Nếu bạn muốn căn chỉnh chuỗi để sử dụng đúng >thay vì <:

>>> '{0: >5}'.format('ss')
'   ss'

Chỉnh sửa: Như đã đề cập trong các nhận xét: số 0 cho biết chỉ mục của đối số được chuyển đến str.format().


5
Ngoài ra, số 0 cho biết vị trí của đối số định dạng, vì vậy bạn có thể làm hai việc khác: '{<5}'.format('ss') 'ss 'giống như trước đây, nhưng không có số 0, thực hiện điều tương tự hoặc 'Second {1: <5} and first {0: <5}'.format('ss', 'sss') 'Second sss and first ss 'vì vậy bạn có thể sắp xếp lại hoặc thậm chí xuất cùng một biến nhiều lần trong một đầu ra duy nhất chuỗi.
strongpile

14
Tôi không còn có thể chỉnh sửa nhận xét trước đó, cần nó. {<5}không hoạt động, nhưng {: <5}không hoạt động mà không có giá trị chỉ mục.
strongpile

9
Đây là Ngôn ngữ thu nhỏ đặc tả định dạng Python mô tả các chuỗi định dạng này và các tùy chọn bổ sung. Để tham khảo nhanh chóng, không gian trong {0: <5}[fill] , những <[align], và 5[width]
cod3monk3y

2
Đó 5 có thể là một thay thế biến>>> print width 20 >>> print "{0: <{width}}".format("ssssss", width=width).split('\n') ['ssssss '] >>>
user2763554

4
Bạn cũng có thể sử dụng số và chỉ cần liệt kê các biến theo thứ tự width=10; "{0: <{1}}".format('sss', width). Hoặc thậm chí bỏ qua những con số'{: <{}}'.format('sss', width)
joelostblom

71

Ban đầu được đăng dưới dạng một bản chỉnh sửa cho câu trả lời của @ 0x90, nhưng nó đã bị từ chối vì đi chệch mục đích ban đầu của bài đăng và được đề nghị đăng dưới dạng nhận xét hoặc câu trả lời, vì vậy tôi bao gồm đoạn viết ngắn ở đây.

Ngoài câu trả lời từ @ 0x90, cú pháp có thể linh hoạt hơn bằng cách sử dụng một biến cho chiều rộng (theo nhận xét của @ user2763554):

width=10
'{0: <{width}}'.format('sss', width=width)

Hơn nữa, bạn có thể làm cho biểu thức này ngắn gọn hơn, bằng cách chỉ sử dụng các số và dựa vào thứ tự của các đối số được chuyển đến format:

width=10
'{0: <{1}}'.format('sss', width)

Hoặc thậm chí bỏ qua tất cả các con số để có độ nhỏ gọn tối đa, có khả năng không ẩn ý:

width=10
'{: <{}}'.format('sss', width)

Cập nhật 2017-05-26

Với sự ra đời của các ký tự chuỗi được định dạng (viết tắt là "f-string") trong Python 3.6, giờ đây có thể truy cập các biến đã xác định trước đó bằng cú pháp ngắn gọn:

>>> name = "Fred"
>>> f"He said his name is {name}."
'He said his name is Fred.'

Điều này cũng áp dụng cho định dạng chuỗi

>>> width=10
>>> string = 'sss'
>>> f'{string: <{width}}'
'sss       '

Tôi thực sự thích câu trả lời này nhất!
Syrtis Major

10

formatchắc chắn là cách thanh lịch nhất, nhưng bạn không thể sử dụng điều đó với loggingmô-đun của python , vì vậy đây là cách bạn có thể thực hiện bằng cách sử dụng %định dạng:

formatter = logging.Formatter(
    fmt='%(asctime)s | %(name)-20s | %(levelname)-10s | %(message)s',
)

Ở đây, -chỉ số căn lề trái và số ở trước sbiểu thị chiều rộng cố định.

Một số đầu ra mẫu:

2017-03-14 14:43:42,581 | this-app             | INFO       | running main
2017-03-14 14:43:42,581 | this-app.aux         | DEBUG      | 5 is an int!
2017-03-14 14:43:42,581 | this-app.aux         | INFO       | hello
2017-03-14 14:43:42,581 | this-app             | ERROR      | failed running main

Thông tin thêm về tài liệu ở đây: https://docs.python.org/2/library/stdtypes.html#string-formatting-operations


Tuy nhiên, điều này sẽ không rút ngắn các chuỗi trên 20 ký tự. Sử dụng '%(name)20.20s'bộ 20 vừa là độ dài chuỗi tối thiểu và tối đa!
xjcl

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.