1

我最近一直在学习 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 个数字的对齐行,计算最大宽度加一;但我几乎确信有一个:

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

无论如何我都不是大 O 方面的专家,但我相信我的两个 for 循环将其从 O(n) 更改为至少 O(2n),所以我真的很想看看是否有可能以某种方式将它们组合起来. 我也不太热衷于我的format_string声明,有没有更好的方法呢?你没有帮我在作业或任何事情上作弊,我认为这会通过大多数 Python 课程,我只是想更多地了解 Python 的思维方式,因为我主要来自 Perl(不确定它是否显示: )。提前致谢!

4

4 回答 4

5
  • 你不需要format_string每次都做。使用str.rjust,您不需要使用格式字符串。
  • 不要使用x % num_row(列表的元素),而是使用(i基于 1 的索引 using 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
于 2013-08-06T07:37:50.057 回答
1

我认为您可以对 maxlength 进行更多的 Pythonic 计算 :)

max_length = len(str(max(a)))

如果你的数字可能是负数或浮动

max_length = max([len(str(x)) for x in a])
于 2013-08-06T07:37:09.357 回答
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))),
于 2013-08-06T07:52:02.423 回答
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需要丢弃行索引(for _, x in g)。只剩下 string x,它像以前一样被正确调整,然后正确调整的字符串join在它们之间带有空格。生成的字符串已准备好作为完整的行打印。

于 2013-08-06T08:51:34.300 回答