因此,在使用格式说明符解决了有关对齐的多个问题之后,我仍然无法弄清为什么将数字数据以波浪的方式打印到stdout。
def create_data(soup_object,max_entry=None):
max_=max_entry
entry=dict()
for a in range(1,int(max_)+1):
entry[a]={'Key':a,
'Title':soup_object[a].div.text.strip(),
'Link':soup_object[a].div.a['href'],
'Seeds':soup_object[a](attrs={'align':'right'})[0].text.strip(),
'Leechers':soup_object[a](attrs={'align':'right'})[1].text.strip()}
yield entry[a]
tpb_get_data=tuple(create_data(soup_object=tpb_soup.body.table.find_all("tr"),max_entry=5))
for data in tpb_get_data:
print('{0} {1:<11} {2:<25} {3:<25} '.format(data['Key'], data['Title'], data['Seeds'],data['Leechers']))
我尝试将f-strings与格式说明符一起使用,但它仍以以下方式打印数据,有人可以帮我解决这个问题。
1 Salvation.S02E11.HDTV.x264-KILLERS 262 19
2 Salvation.S02E13.WEB.x264-TBS[ettv] 229 25
3 Salvation.S02E08.HDTV.x264-KILLERS 178 21
4 Salvation.S02E01.HDTV.x264-KILLERS 144 11
5 Salvation.S02E09.HDTV.x264-SVA[ettv] 129 14
我已经阅读了有关此问题的大多数问题,我想知道是否存在一种原始方法,而不是使用像tabulate这样的库做得很好。但是我也想学习如何在没有任何库的情况下做到这一点。
答案 0 :(得分:3)
由于未正确计算标题的长度,因此得到未对齐的结果。您只保留了11个字符,其中第一个字符已长34个字符。
最简单的方法就是为您计算程序数:
key_len,title_len,seed_len,leech_len = ( max(len(item[itemname]) for item in tpb_get_data) for itemname in ['Key','Title','Seeds','Leechers'] )
fmtstring = '{{:{:d}}} {{:{:d}}} {{:{:d}}} {{:{:d}}}'.format(key_len,title_len,seed_len,leech_len)
for data in tpb_get_data:
print(fmtstring.format(data['Key'], data['Title'], data['Seeds'],data['Leechers']))
效果更好
1 Salvation.S02E11.HDTV.x264-KILLERS 262 19
2 Salvation.S02E13.WEB.x264-TBS[ettv] 229 25
3 Salvation.S02E08.HDTV.x264-KILLERS 178 21
4 Salvation.S02E01.HDTV.x264-KILLERS 144 11
5 Salvation.S02E09.HDTV.x264-SVA[ettv] 129 14
(仅限其他)
这是一种更通用的方法,它使用要打印的键名列表,并能够即时生成所有其他必需的变量。它不需要对变量名进行硬编码,也不需要固定它们的顺序-顺序是从该列表中获取的。要显示所有项目的调整都放在一个位置:同一列表get_items
。可以在fmtstring
行中更改输出分隔符,例如,使用制表符或项目之间的更多空格。
get_items = ['Key','Title','Leechers','Seeds']
lengths = ( max(len(item[itemname]) for item in tpb_get_data) for itemname in get_items )
fmtstring = ' '.join(['{{:{:d}}}' for i in range(len(get_items))]).format(*lengths)
for data in tpb_get_data:
print(fmtstring.format(*[data[key] for key in get_items]))
它的工作原理如下:
lengths
列表中填充了从get_items
列表中提取的每个命名键的最大长度。list
; fmtstring
对以上每一项重复格式指令{:d}
,并填写数字。外部{{:
和}}
被format
转换为{:
和}
,因此对于每个长度,最终结果将是{:number}
。这些单独的格式字符串将合并为一个更长的格式字符串。get_items
中的项目。列表理解查找它们; *
表示法强制将列表“写”为单独的值,而不是将整个列表返回为一个。感谢@Georgy建议您寻找一种不太硬编码的品种。
答案 1 :(得分:1)
如前所述,您错误地计算了字符串的长度。
不用硬编码它们,而是将此任务委托给您的程序。
这是一种通用方法:
CREATE SEQUENCE shared_seq;
CREATE TABLE a (
col1 bigint DEFAULT nextval('shared_seq'),
...
);
CREATE TABLE b (
col1 bigint DEFAULT nextval('shared_seq'),
...
);
示例:
from operator import itemgetter
from typing import (Any,
Dict,
Iterable,
Iterator,
List,
Sequence)
def max_length(objects: Iterable[Any]) -> int:
"""Returns maximum string length of a sequence of objects"""
strings = map(str, objects)
return max(map(len, strings))
def values_max_length(dicts: Sequence[Dict[str, Any]],
*,
key: str) -> int:
"""Returns maximum string length of dicts values for specific key"""
return max_length(map(itemgetter(key), dicts))
def to_aligned_data(dicts: Sequence[Dict[str, Any]],
*,
keys: List[str],
sep: str = ' ') -> Iterator[str]:
"""Prints a sequence of dicts in a form of a left aligned table"""
lengths = (values_max_length(dicts, key=key)
for key in keys)
format_string = sep.join(map('{{:{}}}'.format, lengths))
for row in map(itemgetter(*keys), dicts):
yield format_string.format(*row)
有关更多信息,请参见docs。也有对齐的示例。
答案 2 :(得分:0)
很好的答案购买@Jongware,只是为了
这里是:
def print_list_of_dicts_as_table(list_of_dicts, keys=None):
# assuming all dicts have same keys
first_entry = list_of_dicts[0]
if keys is None:
keys = first_entry.keys()
num_keys = len(keys)
max_key_lens = [
max(len(str(item[k])) for item in list_of_dicts) for k in keys
]
for k_idx, k in enumerate(keys):
max_key_lens[k_idx] = max(max_key_lens[k_idx], len(k))
fmtstring = (' | '.join(['{{:{:d}}}'] * num_keys)).format(*max_key_lens)
print(fmtstring.format(*first_entry.keys()))
print(fmtstring.format(*['-'*key_len for key_len in max_key_lens]))
for entry in list_of_dicts:
print(fmtstring.format(*entry.values()))
用法示例:
a=[{'a':'asdd','b':'asd'},{'a':'a','b':'asdsd'},{'a':1,'b':232323}]
print_list_of_dicts_as_table(a)
输出:
a | b
---- | ------
asdd | asd
a | asdsd
1 | 232323