web-dev-qa-db-ja.com

インデックス変数なしで何かをN回行うPythonの方法?

毎日pythonが大好きです。

今日、私は次のようなコードを書いていました。

for i in xrange(N):
    do_something()

私は何回かしなければなりませんでした。しかし、毎回i(インデックス変数)の値に依存しませんでした。使用したことのない変数(i)を作成していることに気付き、「その役に立たないインデックス変数を必要とせずに、もっとPython的な方法が確実にある」と考えました。

質問は次のとおりです。この単純なタスクをより(Pythonの)美しい方法で行う方法を知っていますか?

138
Manuel Aráoz

xrange(N)でループするよりも少し速い方法は次のとおりです。

import itertools

for _ in itertools.repeat(None, N):
    do_something()
100
Alex Martelli

これを尋ねたときに学んだように、_変数を使用します question 、たとえば:

# A long way to do integer exponentiation
num = 2
power = 3
product = 1
for _ in xrange(power):
    product *= num
print product
51
GreenMatt

私はfor _ in range(n)を使用していますが、それは要点にまっすぐです。 Python 2の膨大な数のリスト全体を生成しますが、Python 3を使用している場合は問題ありません。

_はxと同じものです。ただし、使用するつもりのない識別子を示すために使用されるpythonイディオムです。 pythonでは、これらの識別子は他の言語の変数のように覚えたりスペースを割り当てたりしません。忘れがちです。それらはオブジェクトを指す単なる名前であり、この場合は各反復の整数です。

9
Khorkrak

関数はファーストクラスの市民なので、小さなラッパーを書くことができます(Alexの回答から)

def repeat(f, N):
    for _ in itertools.repeat(None, N): f()

関数を引数として渡すことができます。

9
Anycorn

さまざまな回答が非常にエレガントであることがわかりました(特にAlex Martelliの回答)が、パフォーマンスを直接定量化したかったので、次のスクリプトを作成しました。

from itertools import repeat
N = 10000000

def payload(a):
    pass

def standard(N):
    for x in range(N):
        payload(None)

def underscore(N):
    for _ in range(N):
        payload(None)

def loopiter(N):
    for _ in repeat(None, N):
        payload(None)

def loopiter2(N):
    for _ in map(payload, repeat(None, N)):
        pass

if __== '__main__':
    import timeit
    print("standard: ",timeit.timeit("standard({})".format(N),
        setup="from __main__ import standard", number=1))
    print("underscore: ",timeit.timeit("underscore({})".format(N),
        setup="from __main__ import underscore", number=1))
    print("loopiter: ",timeit.timeit("loopiter({})".format(N),
        setup="from __main__ import loopiter", number=1))
    print("loopiter2: ",timeit.timeit("loopiter2({})".format(N),
        setup="from __main__ import loopiter2", number=1))

また、Martelliのソリューションに基づいて、map()を使用してペイロード関数を呼び出す代替ソリューションを思い付きました。 OK、ペイロードが破棄されるパラメーターを受け入れるようにするという自由を選んだという点で、私は少しごまかしました。これを回避する方法があるかどうかはわかりません。それにもかかわらず、結果は次のとおりです。

standard:  0.8398549720004667
underscore:  0.8413165839992871
loopiter:  0.7110594899968419
loopiter2:  0.5891903560004721

したがって、mapを使用すると、標準forループよりも約30%、Martelliの場合よりもさらに19%改善されます。

5
japs

do_somethingを関数として定義し、それをN回実行したいとします。たぶん、あなたは以下を試すことができます:

todos = [do_something] * N  
for doit in todos:  
    doit()
4
Cox Chen

単純なwhileループはどうですか?

while times > 0:
    do_something()
    times -= 1

すでに変数があります。なぜそれを使用しないのですか?

0
Carlos Ramirez