ネストされたループでさえ、常に1行のループを使用していますか?私は、多くの人が "one-liners"を愛しているのを見ていますが、私にとっては、特に入れ子になったループについて言えば、時々読みにくいです。Pythonでの1行ステートメントの有用性
これまでに見たネストループのほとんどは、1行につき79文字を超えています。
「one-liners」がコンパクトであれば何か別のものを提供しているかどうかを知りたいですか?おそらくメモリを少なくしますか?
ネストされたループでさえ、常に1行のループを使用していますか?私は、多くの人が "one-liners"を愛しているのを見ていますが、私にとっては、特に入れ子になったループについて言えば、時々読みにくいです。Pythonでの1行ステートメントの有用性
これまでに見たネストループのほとんどは、1行につき79文字を超えています。
「one-liners」がコンパクトであれば何か別のものを提供しているかどうかを知りたいですか?おそらくメモリを少なくしますか?
はい、より多くのコードがC言語で実行される可能性があります(明示的なループでは、すべての即時ステップをインタプリタで利用できなければならない、ワンライナーリストの理解度が必要です)。
import timeit
def f1():
result = []
for x in range(100):
for y in range(100):
result.append(x * y)
return result
def f2():
return [x * y for y in range(100) for x in range(100)]
print('loop: ', timeit.timeit(f1, number=1000))
print('oneliner:', timeit.timeit(f2, number=1000))
結果(Pythonの3):
loop: 1.2545137699926272
oneliner: 0.6745600730064325
偉大な答えは、私が探していたものです。私はリスト内包に潜入し、それらを適切に学習するときのように見えます。好奇心の外に:79文字のPEP推奨を超える長い入れ子になったループに出くわしたら? (私はiterator 'x'またはそれを短く保つのに似たような名前をつけることができることを知っていますが、それでも79文字を超えるとしたらどうでしょう?) – narn
[list comprehensionsで改行を使うことができます](http://stackoverflow.com/questions/5809059/line-continuation-for-list-comprehensions-or-generator-expressions-in-python)を参照してください。デカルトネストループのもう1つの一般的なテクニックは、ネストループではなく['itertools.product'](https://docs.python.org/3/library/itertools.html#itertools.product)です。 –
1つのライナーに依存して、より効率的で読みやすいものもあります。
リストの理解の場合をとります。あなたがそうのようなループのためにそれを行うことができます[2,4,6,...,18,20]
:出力[1,2,3,...,9,10]
:入力2
を乗じた彼らの製品のリストあなたは1から10までのすべての数字を取るしたいとして出力することができます:
output = []
for i in range(1, 11):
output.append(i*2)
それともリストの内包表記を使用することができます。
[i*2 for i in range(1,11)]
あなたはリットルが表示されますistの理解は非常に速く、また非常に読みやすいです。
dictの理解、set comprehension、generatorの表現についても同じことが言えます。また、理解できる限り、map()
とfilter()
の使用を強く推奨します。
はいそのすべてが回避されるリスト内包で.append
メソッド呼び出し、メソッドのルックアップなどのオーバーヘッドもあります。これは良い習慣です。
通常、経験豊富なプログラマは、匿名関数(lambda:http://www.secnetix.de/olli/Python/lambda_functions.hawkを参照)を1行のループで使用することにより、パフォーマンスが向上します。
議論のため...彼らはすべて同じです。
「」リスト内包...喫煙ワンライナー... 「はB」と同じことができますが、リストの内包内の注釈を提供することができます...それは技術的にはまだワンライナー 'ですc 'は従来のアプローチです。 スピードが懸念される場合は、同じ仕事の日を外で実行するのでなければスピードがあまり心配されず、実行には本当に時間がかかります。あなたがマイクロ秒またはナノ秒に話しているときのスピードを比較することは、学問的な関心があるかもしれませんが、大部分のユーザーには影響しません。 私はいつもコードのコンパクトさよりも表現の明快さに投票します。
a = [i**2 for i in range(20) if i > 5 and i < 10]
b = [i**2 # do this
for i in range(20) # using these
if (i > 5) and # where this and
(i < 10) # this is good
]
c = []
for i in range(20):
if (i > 5) and (i < 10):
c.append(i**2)
EDIT数値の範囲の生成物を製造する与えられた例では、onelinerが問題である必要はないことが、良好な指標であるが、この方法は、結果を得るために使用されます。私は、10個の値を使って製品を決定する方法を説明します...あなたが好きなら100で試してみてください。フルフォーマットでやるが、必要ならばすべてをオンライナーに減らすことができる(インポートは除外)。
>>> import numpy as np
>>> a = np.arange(10)
>>> b = np.arange(10).reshape(10,1)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> b
array([[0],
[1],
[2],
[3],
[4],
[5],
[6],
[7],
[8],
[9]])
>>> a*b
array([[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
[ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18],
[ 0, 3, 6, 9, 12, 15, 18, 21, 24, 27],
[ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36],
[ 0, 5, 10, 15, 20, 25, 30, 35, 40, 45],
[ 0, 6, 12, 18, 24, 30, 36, 42, 48, 54],
[ 0, 7, 14, 21, 28, 35, 42, 49, 56, 63],
[ 0, 8, 16, 24, 32, 40, 48, 56, 64, 72],
[ 0, 9, 18, 27, 36, 45, 54, 63, 72, 81]])
またはワンライナー
>>> out = np.arange(10) * np.arange(10).reshape(10,1)
として、そしてもちろん、私が示されている完全な表現なしでこれを行うための組み込み関数があります。
スピードがすべてではありません。コードを明確にし、適切なツールを選択することがまず必要です。
'if i> 5とi < 10' ->' if 5
さらに優れた選択肢を表示するために私の補遺をチェックしてください。このオプションは、データ入力が非常に大きい場合にうまく調整されます。これは別の考慮事項です。すべてのアプローチが一様に時間を取らず、しばしばデータサイズに依存しています。 – NaN
「numpyを使用する」とは、リスト内包表記の代わりになりますか? numpyは数値計算専用の(サードパーティー)ライブラリですが、リスト内包表記(およびその他の1ライナー)は一般的なもので数値計算に関係しない多くの異なるケースに使用されます。 – UnholySheep
特定の1ライナーに依存します。特定のPython構造体(例:リスト内包表記)は、リストを埋めるために通常のfor-loopを書くよりも、より良い機械コードを生成するためにインタープリタによって最適化される可能性があります。しかし、コードの可読性が複雑すぎると指摘しているように、コードを読むことができなくなって(したがって、維持不能になる)どの時点で決定するのがプログラマーの仕事です。 – UnholySheep
理解できないものがある場合に役立ちます。しばしば、正しい命名法と空白を使用することによって救済できます。しかし、具体的なサンプルなしでデモするのは難しいです。 –
私の例では、積み重ねられたリストの理解だけを見てください。技術的には物理ライナーでなくてもかまいません。 – NaN