中文字符打印对齐
大佬们求助,写了个tabular_printing()函数用于表格样式打印数据,但是含有中文的部分没法对齐,如下图所示:https://s21.ax1x.com/2024/10/10/pAJaeBV.png
from faker import Faker
from typing import List, Tuple
def generate_data(faker):
return (
faker.name(),
faker.country(),
faker.phone_number(),
faker.ssn(),
faker.ascii_free_email(),
faker.date(),
faker.company()
)
element = Tuple
fk1 = Faker(locale="en_US")
fk2 = Faker(locale="zh_CN")
data =
data.insert(2, generate_data(faker=fk2))
def tabular_printing(headers: Tuple, data: List) -> None:
table_rows =
table_rows.extend((str(i),) + row for i, row in enumerate(iterable=data, start=1))
column_widths =
separator = f"+{'+'.join('-' * (w + 2) for w in column_widths)}+"
sheet =
for row in table_rows:
sheet.append(f"|{'|'.join(f' {item:^{w}} ' for item, w in zip(row, column_widths))}|")
sheet.append(separator)
print(*sheet, sep="\n")
if __name__ == '__main__':
headers = ("", "Name", "Country", "PhoneNumber", "IDCard", "E-mail", "Birthday", "Company")
tabular_printing(headers=headers, data=data)
处理中文字符对齐问题时,主要是因为中英文字符的宽度不同。中文字符宽度通常比英文宽度大,导致用相同空格补齐时对齐出现问题。
可以通过以下方法解决此问题:
1. 使用 `str` 模块的 `str.width()` 方法获取字符的实际宽度。可使用如下函数来计算宽度:
import unicodedata
def get_display_width(s):
return sum(2 if unicodedata.east_asian_width(char) in 'FWA' else 1 for char in s)
2. 修改 `tabular_printing()` 函数以支持宽度计算:
def tabular_printing(headers: Tuple, data: List) -> None:
table_rows = []
table_rows.append(headers)
table_rows.extend((str(i),) + row for i, row in enumerate(iterable=data, start=1))
# 计算列宽,考虑中文字符宽度
column_widths = [
max(get_display_width(str(item)) for item in column)
for column in zip(*table_rows)
]
separator = f"+{'+'.join('-' * (w + 2) for w in column_widths)}+"
sheet = []
sheet.append(separator)
for row in table_rows:
formatted_row = "|".join(
f" {item}{' ' * (w - get_display_width(item))} " for item, w in zip(row, column_widths)
)
sheet.append(f"|{formatted_row}|")
sheet.append(separator)
print(*sheet, sep="\n")
这样调整后,函数应该可以处理中英文混合的情况,并实现表格对齐。确保在每个位置使用适当的空格量填充字符,从而实现美观的对齐效果。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 @FishC变化倒是有,但还是没有对齐https://s21.ax1x.com/2024/10/10/pAJa139.png 糖醋咸鱼微辣 发表于 2024-10-10 12:52
@FishC变化倒是有,但还是没有对齐https://s21.ax1x.c ...
看来您遇到了字符宽度计算的问题。中文字符在打印时通常比英文字符占用更多的空间。为了解决这个问题,我们可以使用 `unicodedata` 模块来判断字符宽度。这是一个处理字符宽度的简单示例:
import unicodedata
from typing import List, Tuple
from faker import Faker
def generate_data(faker):
return (
faker.name(),
faker.country(),
faker.phone_number(),
faker.ssn(),
faker.ascii_free_email(),
faker.date(),
faker.company()
)
def get_display_width(s: str) -> int:
"""Calculate width of string for display purpose, considering Chinese and full-width chars."""
return sum(2 if unicodedata.east_asian_width(char) in 'WF' else 1 for char in s)
def tabular_printing(headers: Tuple, data: List) -> None:
# Add row numbers
table_rows = + [(str(i),) + row for i, row in enumerate(data, start=1)]
# Determine the maximum width needed for each column
column_widths =
# Print the separator
separator = f"+{'+'.join('-' * (w + 2) for w in column_widths)}+"
print(separator)
# Print each row of the table
for row in table_rows:
formatted_row = "|".join(
f" {item}{' ' * (w - get_display_width(item))} " for item, w in zip(row, column_widths)
)
print(f"|{formatted_row}|")
print(separator)
if __name__ == '__main__':
headers = ("", "Name", "Country", "PhoneNumber", "IDCard", "E-mail", "Birthday", "Company")
fk1 = Faker(locale="en_US")
fk2 = Faker(locale="zh_CN")
data = [
generate_data(faker=fk1),
generate_data(faker=fk2),
generate_data(faker=fk1)
]
tabular_printing(headers=headers, data=data)
在 `get_display_width` 函数中,我们使用 `unicodedata.east_asian_width` 来判断字符是否为全宽字符(如中文字符),并将其宽度计算为 2,否则为 1。通过这种方式,您应该能够更好地对齐中英文字符混合的表格。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页:
[1]