จัดรูปแบบสตริงผลลัพธ์การจัดตำแหน่งด้านขวา


149

ฉันกำลังประมวลผลไฟล์ข้อความที่มีพิกัด x, y, z

     1      128  1298039
123388        0        2
....

ทุกบรรทัดถูกคั่นด้วย 3 รายการโดยใช้

words = line.split()

หลังจากประมวลผลข้อมูลฉันจำเป็นต้องเขียนพิกัดกลับมาในไฟล์ txt อื่นเพื่อให้รายการในแต่ละคอลัมน์ชิดกัน (เช่นเดียวกับไฟล์อินพุต) ทุกบรรทัดประกอบด้วยพิกัด

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

มีโปรแกรมจำพวกอย่างstd::setw()อื่นใน C ++ ที่อนุญาตให้ตั้งค่าความกว้างและการจัดแนวหรือไม่?

คำตอบ:


230

ลองวิธีนี้โดยใช้str.formatไวยากรณ์ที่ใหม่กว่า:

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

และนี่คือวิธีการใช้%ไวยากรณ์เก่า(มีประโยชน์สำหรับ Python เวอร์ชันเก่าที่ไม่สนับสนุนstr.format):

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

39
สังเกตว่าไวยากรณ์ "เก่า" สะอาดและอ่านง่ายและสั้นอย่างไร
fyngyrz

2
ฉันคิดว่าฉันจะเพิ่มลิงค์โดยตรงมากกว่าที่มีให้: docs.python.org/2/library/…
brw59

48
สั้นลงแน่นอนว่าฉันไม่เข้าใจความหมายที่แท้จริง แต่การอ่านง่ายขึ้นนั้นเป็นเพราะฉันคุ้นเคย หากคุณยังไม่คุ้นเคยกับรูปแบบใดรูปแบบใหม่อ่านง่ายกว่า ".format" สำหรับการจัดรูปแบบสตริงดูเหมือนจะง่ายกว่าร้อยละ / โมดูโล ลูกศรขวาสำหรับการจัดตำแหน่งที่เหมาะสมดูเหมือนว่าใช้งานง่ายเกินไป
Mark

2
@ Mark ทางเดียวที่เก่ากว่าคือสะอาดกว่าคือใช้ตัวอักษรน้อยลง ใช่ด้วยความคุ้นเคยวิธีใหม่นี้จะกลายเป็นเรื่องง่าย แต่ก็ไม่ได้สะอาดและง่ายกว่า วิธีเก่านั้นใช้ง่ายกว่าสำหรับผู้ที่คุ้นเคยกับไวยากรณ์ที่มากับเราผ่านภาษา C ซึ่งเป็นภาษาที่มีความกระชับและแม่นยำ มีวิธีอะไรก่อนหน้าสำหรับวิธีการใหม่?
สตีเฟ่นบอสตัน

2
@StephenBoston ฉันจะปล่อยให้ผู้เชี่ยวชาญอ่าน แต่วิธีการใหม่จะสะอาดกว่าเดิมอย่างแน่นอน Parens ไม่มีทางเลือกอีกต่อไป สามารถสับสนกับตัวดำเนินการทางคณิตศาสตร์ (แม้ว่าจะไม่ได้อยู่ในบริบท แต่อย่างรวดเร็ว) วิธีการแบบเก่าจะล้มเหลวหากคำ [n] ไม่ใช่ประเภทที่คาดหวัง (สตริงในกรณีนี้) วิธีใหม่ไม่จำเป็นต้องรู้ว่าประเภทขาเข้าคืออะไรมันใช้งานได้เสมอ สะอาดและเรียบง่าย เพื่อความเป็นธรรมฉันไม่เคยพอใจกับสไตล์การพิมพ์ (ฉันส่วนใหญ่ใช้ C กับ cout)
ซิม


51

คุณสามารถจัดแนวเช่นนั้น:

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

โดยที่>หมายถึง " จัดชิดขวา " และ8เป็นความกว้างสำหรับค่าเฉพาะ

และนี่คือหลักฐาน:

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


       1      128  1298039
  123388        0        2

ps *lineหมายถึงlineรายการที่จะแตกออกเพื่อ.format(*line)ทำงานในทำนองเดียวกันกับ.format(line[0], line[1], line[2])(สมมติว่าlineเป็นรายการที่มีเพียงสามองค์ประกอบ)



18

นี่เป็นอีกวิธีที่คุณสามารถจัดรูปแบบโดยใช้รูปแบบ '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}",
)

สิ่งนี้จะให้ผลลัพธ์ต่อไปนี้:

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

สิ่งที่คุณกำลังทำอยู่ที่นี่คือคุณกำลังบอกว่าคอลัมน์แรกมีความยาว 15 ตัวอักษรและมันถูกทิ้งให้เป็นธรรมและคอลัมน์ที่สอง (ค่า) มีความยาว 10 ตัวอักษรและเป็นธรรมที่ถูกต้อง


มีวิธีการเปรียบเทียบความกว้างของรูปแบบหรือไม่ ในตัวอย่างนี้ถ้าคุณตัดสินใจที่จะเปลี่ยนการจัดรูปแบบเป็นความกว้าง 20 และ 15 ต้องเปลี่ยนหลายบรรทัด widths = [15, 10] f"{'Trades:':<width[0]}{cnt:>width[1]}",ฉันต้องการได้รับ sth เหมือนด้านบน
Tomasz Sabała

1
เข้าใจแล้ว! บางทีบางคนอาจพบว่ามีประโยชน์ ฉันต้องการวงเล็บซ้อนกันอีกหนึ่งอันสำหรับสิ่งนี้:f"{'Trades:':<{width[0]}}{cnt:>{width[1]}}"
Tomasz Sabała

1
บางครั้งคำตอบที่ดีที่สุดคือคำตอบที่ไม่ตอบคำถาม ขอบคุณสำหรับสิ่งนี้! :)
Brian Wiley

5

ตารางอย่างง่ายของการส่งออก:

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

เอาท์พุท:

variable a    variable b
      0.33         66.67

% 10.2f: 10 คือความยาวต่ำสุดและ 2 คือจำนวนตำแหน่งทศนิยม


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.