我最近一直在学习Python,今晚我正在玩几个例子,我只是想出了以下内容:
#!/usr/bin/env python
a = range(1,21) # Range of numbers to print
max_length = 1 # String length of largest number
num_row = 5 # Number of elements per row
for l in a:
ln = len(str(l))
if max_length <= ln:
max_length = ln
for x in a:
format_string = '{:>' + str(max_length) + 'd}'
print (format_string).format(x),
if not x % num_row and x != 0:
print '\n',
其中输出以下内容:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
脚本正在做我想要的,即每行打印5行数的对齐行,计算最大宽度加1;但我几乎确信有一个:
我不是大O的专家,但我相信我的两个for循环会将其从O(n)更改为至少O(2n),所以我真的很想看看是否可以以某种方式结合它们。我也不太热衷于我的format_string
声明,有没有更好的方法呢?你没有帮我欺骗家庭作业或任何东西,我认为这会通过大多数Python课程,我只想更多地围绕Python的思维方式,因为我主要来自Perl(不确定它是否显示: )。提前谢谢!
答案 0 :(得分:5)
format_string
。使用str.rjust,您不需要使用格式字符串。x % num_row
(使用i
的基于1的索引),而不是使用enumerate(a, 1)
(列表元素)。想一个案例a = range(3, 34)
。
i == 0
,因为i
永远不会0
。not x % num_row
很难理解。请改用x % num_row == 0
。a = range(1,21)
num_row = 5
a = map(str, a)
max_length = len(max(a, key=len))
for i, x in enumerate(a, 1):
print x.rjust(max_length),
if i % num_row == 0:
print
答案 1 :(得分:1)
我认为你可以做更多pythonic计算maxlength:)
max_length = len(str(max(a)))
如果您的号码可能是负数或浮动
max_length = max([len(str(x)) for x in a])
答案 2 :(得分:1)
另一个条目。只需添加一个函数式编程。 : - )
n = 20
f = lambda x: str(x).rjust(len(str(n+1))) + (" " if x % 5 else "\n")
print "".join(map(f, range(1,n+1))),
答案 3 :(得分:0)
我不确定这不是一个悲观的:-)但是建立在falsetru的答案上,我们可以使用itertools.groupby
按行索引对每一行进行分组。因为groupby
需要一个键,我们必须enumerate
这些值,然后丢弃枚举索引:
a = range(1,21)
num_row = 5
a = map(str, a)
max_length = len(max(a, key=len))
(与之前相同,但现在:)
from itertools import groupby
# assumes / is integer division - use // if needed
# (I had // but SO formats it as a comment)
for _, g in groupby(enumerate(a), lambda x: x[0] / num_row):
print ' '.join(x.rjust(max_length) for _, x in g)
这里每个组g
由构成每一行的所有(枚举)值组成,其行号在前面,因此' '.join
的内部生成器需要丢弃行索引({ {1}})。只留下字符串for _, x in g
,它像以前一样正确调整,然后右调整的字符串x
,它们之间有空格。生成的字符串已准备好作为完整的行打印。