次のジェネレータ式を反復処理する場合、
fun(i) for i in mylist if i not in setA.union(setB)
メソッドはsetA.union
各反復で呼び出されますか、それとも1回だけ呼び出されますか?
次のジェネレータ式を反復処理する場合、
fun(i) for i in mylist if i not in setA.union(setB)
メソッドはsetA.union
各反復で呼び出されますか、それとも1回だけ呼び出されますか?
はい、setA.union(setB)
反復で毎回呼び出されます、
ジェネレータ式の前にこれを実行し、変数に格納する必要があります
setvalues = setA.union(setB)
fun(i) for i in mylist if i not in setvalues
dis
モジュールを使用した簡単な証明:
In [24]: def func():
....: a=set([1,2,3])
....: b=set([3,4,5])
....: c=[i for i in xrange(10) if i in a.union(b)]
....:
In [25]: dis.dis(func)
4 42 BUILD_LIST 0
45 LOAD_GLOBAL 1 (xrange)
48 LOAD_CONST 6 (10)
51 CALL_FUNCTION 1
54 GET_ITER #iterator returned from xrange
>> 55 FOR_ITER 33 (to 91) #until the iterator is not exhausted
58 STORE_FAST 2 (i)
61 LOAD_FAST 2 (i)
64 LOAD_FAST 0 (a)
67 LOAD_ATTR 2 (union)
70 LOAD_FAST 1 (b)
73 CALL_FUNCTION 1 #union() is being called in each iteration
76 COMPARE_OP 6 (in)
79 POP_JUMP_IF_FALSE 55
82 LOAD_FAST 2 (i)
85 LIST_APPEND 2
88 JUMP_ABSOLUTE 55
#end of loop
>> 91 STORE_FAST 3 (c)
94 LOAD_CONST 0 (None)
97 RETURN_VALUE
したがって、あなたの例では、それは各反復、つまりlen(mylist)
時間で呼び出されます。
それを検証する別の方法は、それをプロファイリングすることです。@AshwiniChaudharyから例を借りて、cProfileで実行します
>>> def func():
a=set([1,2,3])
b=set([3,4,5])
c=[i for i in xrange(10) if i in a.union(b)]
>>> import cProfile
>>> cProfile.run("func()")
13 function calls in 0.000 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 <pyshell#1045>:1(func)
1 0.000 0.000 0.000 0.000 <string>:1(<module>)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
10 0.000 0.000 0.000 0.000 {method 'union' of 'set' objects}
10
ここでは、組合は時代と呼ばれていることを明確に述べています