Is next () in python really that fast?

In one of the posts here, I read that using next () to find and get the first occurrence of an item in a list can be quick. However, I was stunned to see that the traditional if-break syntax worked best for a while. Correct me if I made a mistake in my analysis. Here is a snippet of what I tried:

>>> def compare_2():
...     device = 'a'
...     l = ['a', 'b', 'c', 'd']
...     z = next((device for x in l if x==device), None)

>>> def compare_1():
...     device = 'a'
...     l = ['a', 'b', 'c', 'd']
...     z = None
...     for x in l:
...             if x == device:
...                     z = device
...                     break

>>> import timeit
>>> t = timeit.Timer(setup='from __main__ import compare_2', stmt='compare_2()')
>>> t.timeit()
1.5207240581512451
>>> t = timeit.Timer(setup='from __main__ import compare_1', stmt='compare_1()')
>>> t.timeit()
0.46623396873474121

I thought this could happen as I tried to find and retrieve the first item in the list as an example. I also tried with the last element and noticed that next () does not work better than before.

>>> def compare_2():
...     device = 'd'
...     l = ['a', 'b', 'c', 'd']
...     z = next((device for x in l if x==device), None)
...
>>>
>>> def compare_1():
...     device = 'd'
...     l = ['a', 'b', 'c', 'd']
...     z = None
...     for x in l:
...             if x == device:
...                     z = device
...                     break
...

>>>
>>> t = timeit.Timer(setup='from __main__ import compare_2', stmt='compare_2()')
>>> t.timeit()
1.6903998851776123
>>> t = timeit.Timer(setup='from __main__ import compare_1', stmt='compare_1()')
>>> t.timeit()
0.66585493087768555

I would like to know when to actually use next (), and when not, in terms of code optimization. Thank!

UPDATE: if device in l . . . : obj = next (obj obj obj_list, obj.value == 1)

+4
3

, - . , , if x==device , ().

. , , , , :

>>> from timeit import Timer
>>> # List comprehension forces a new list to be created in memory
>>> def f1():
...     q = [x for x in xrange(1000)]
...     r = q[1]
...     return r
... 
>>> # Generator comprehension does 'lazy' iteration, only when needed
>>> def f2():
...     q = (x for x in xrange(1000))
...     r = next(q)
...     return r
... 
>>> Timer(f1).timeit()
47.420308774268435
>>> Timer(f2).timeit()
1.346566078497844

, , , next(), .

, if x = 999:

>>> # List comprehension still forces creation of a new list
>>> # although the list only ends up with one element
>>> # nb. it the last element
>>> def f1():
...     q = [x for x in xrange(1000) if x == 999]
...     r = q[0]
...     return r
... 
>>> # Generator comprehension is lazy
>>> # nb. it also only returns the last element
>>> def f2():
...     q = (x for x in xrange(1000) if x == 999)
...     r = next(q)
...     return r
... 
>>> Timer(f1).timeit()
37.279105355189984
>>> Timer(f2).timeit()
37.46816399778598

, . . , , , .

, , , , , , .

, , if x==device, , , .

, , for, , , next() .

: , Python: PEP-0289 -

, [5]:

sum(x for x in foo()). , foo() , sum(), , . , ? , sum() foo(), foo() sum(), , .

OTOH, sum(bar(x) for x in foo()), sum() foo() bugfree, bar() , , bar() , sum() - . ( , () .)

, x==device , , . , , , next() , , , , , , for.

+1

, . , " ", python. for, for iter , , , , , , , , , , . , , , .

, , . , , . , python, , C python (, numpy) C/++.

:

x = [1] * 1000000
x[500000] = 0

def func1(l):
   ...:     for n in l:
   ...:         if n == 0:
   ...:             break
   ...:         

def func2(l):
   ...:     z = next((n for n in x if n == 0))
   ...:     

%timeit func1(x)
100 loops, best of 3: 10.4 ms per loop

%timeit func2(x)
100 loops, best of 3: 10.4 ms per loop

, , , , - , . , , , , , for .

+2

next() . , . , .

>>> timeit.timeit('next((i for i in range(1000)))')
10.571892976760864
>>> timeit.timeit('next((i for i in xrange(1000)))')
0.9348869323730469

, . Python , .

So, next()not faster, but the concept of using iterations and generators when used therefore. And next()was designed for them.

+2
source

All Articles