[coding-style] 인덱스 변수없이 N 번 무언가를하는 pythonic 방법?

매일 저는 점점 더 파이썬을 좋아합니다.

오늘은 다음과 같은 코드를 작성했습니다.

for i in xrange(N):
    do_something()

나는 N 번 무언가를해야했습니다. 그러나 매번 i(인덱스 변수) 의 값에 의존하지 않았습니다 . 나는 내가 결코 사용하지 않은 변수를 만들고 있다는 것을 깨달았고 ( i“) 쓸모없는 색인 변수가 필요 없이이 작업을 수행하는 더 파이썬적인 방법이 있다고 생각했습니다.

그래서 … 질문은 :이 간단한 작업을 좀 더 (파이썬) 아름다운 방법으로 수행하는 방법을 알고 있습니까?



답변

루핑보다 약간 빠른 접근 방식 xrange(N)은 다음과 같습니다.

import itertools

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


답변

질문을 할 때 배운 _ 변수를 사용하십시오 ( 예 :

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


답변

나는 단지을 사용한다 for _ in range(n). 파이썬 2에서는 엄청난 수의 전체 목록을 생성하지만 파이썬 3을 사용하는 경우 문제가되지 않습니다.


답변

함수는 일류 시민이기 때문에 작은 래퍼를 작성할 수 있습니다 (Alex 답변에서)

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

그런 다음 함수를 인수로 전달할 수 있습니다.


답변

_는 x와 같습니다. 그러나 사용하지 않을 식별자를 나타내는 데 사용되는 파이썬 관용구입니다. 파이썬에서 이러한 식별자는 변수가 다른 언어 에서처럼 기억하거나 공간을 할당하지 않습니다. 잊어 버리기 쉽습니다. 그것들은 객체를 가리키는 이름 일뿐입니다.이 경우 각 반복에서 정수입니다.


답변

다양한 답변이 정말 우아하다는 것을 알았지 만 (특히 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 __name__ == '__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 % 더 향상됩니다.


답변

do_something 을 함수로 정의 하고 N 번 수행 한다고 가정합니다 . 아마도 다음을 시도해 볼 수 있습니다.

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