思考Python

时间:2013-08-06 07:29:40

标签: python optimization formatting

我最近一直在学习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;但我几乎确信有一个:

  • 更多“pythonic”方式来做到这一点
  • 更有效的方法来做到这一点。

我不是大O的专家,但我相信我的两个for循环会将其从O(n)更改为至少O(2n),所以我真的很想看看是否可以以某种方式结合它们。我也不太热衷于我的format_string声明,有没有更好的方法呢?你没有帮我欺骗家庭作业或任何东西,我认为这会通过大多数Python课程,我只想更多地围绕Python的思维方式,因为我主要来自Perl(不确定它是否显示: )。提前谢谢!

4 个答案:

答案 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,它们之间有空格。生成的字符串已准备好作为完整的行打印。