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 つの数字の行を整列して印刷し、最大幅に 1 を加えた値を計算します。しかし、次のいずれかがあるとほぼ確信しています。

  • これを行うためのより「pythonic」な方法
  • これを行うためのより効率的な方法。

私は決して大きな O の専門家ではありませんが、私の 2 つの for ループはこれを O(n) から少なくとも O(2n) に変更すると信じているので、何らかの方法でそれらを組み合わせることが可能かどうかを本当に知りたいです。 . 私も自分のformat_string宣言にあまり熱心ではありません。それを行うより良い方法はありますか? あなたは私が宿題や何かをカンニングするのを手伝っていません.これはほとんどのPythonクラスに合格すると思います.私は主にPerlから来ているので、Pythonの考え方に頭を包み込みたいだけです. )。前もって感謝します!

4

4 に答える 4

5
  • format_string毎回作る必要はありません。str.rjustを使用すると、フォーマット文字列を使用する必要はありません。
  • x % num_row(リストの要素) を使用する代わりに、 (を使用したi1 ベースのインデックス) を使用し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

別のエントリ。少し機能的なプログラミングで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 に答える