pythonic way to do something N times without an index variable?

前端 未结 8 1178
一整个雨季
一整个雨季 2020-12-02 08:11

Every day I love python more and more.

Today, I was writing some code like:

for i in xrange(N):
    do_something()

I had to do som

8条回答
  •  醉话见心
    2020-12-02 08:48

    I found the various answers really elegant (especially Alex Martelli's) but I wanted to quantify performance first hand, so I cooked up the following script:

    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))
    

    I also came up with an alternative solution that builds on Martelli's one and uses map() to call the payload function. OK, I cheated a bit in that I took the freedom of making the payload accept a parameter that gets discarded: I don't know if there is a way around this. Nevertheless, here are the results:

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

    so using map yields an improvement of approximately 30% over the standard for loop and an extra 19% over Martelli's.

提交回复
热议问题