g = lambda x:[lambda x:x*1, lambda x:x*x, lambda x:x*x*x, lambda x:42][x%4](x)
[g(x) for x in xrange(12)]
このシーケンスの次の値は何ですか?
試してみましたか?
>>> g = lambda x:[lambda x:x*1, lambda x:x*x, lambda x:x*x*x, lambda x:42][x%4](x)
>>> [g(x) for x in xrange(12)]
[0, 1, 8, 42, 4, 25, 216, 42, 8, 81, 1000, 42]
各値の計算方法は次のとおりです。
[
0, # x is 0, x%4 is 0, so g(x) becomes (lambda x:x*1)(0) or 0*1
1, # x is 1, x%4 is 1, so g(x) becomes (lambda x:x*x)(1) or 1*1
8, # x is 2, x%4 is 2, so g(x) becomes (lambda x:x*x*x)(2) or 2*2*2
42, # x is 3, x%4 is 3, so g(x) becomes (lambda x:42)(3) or 42
4, # x is 4, x%4 is 0, so g(x) becomes (lambda x:x*1)(4) or 4*1
25, # x is 5, x%4 is 1, so g(x) becomes (lambda x:x*x)(5) or 5*5
216, # x is 6, x%4 is 2, so g(x) becomes (lambda x:x*x*x)(6) or 6*6*6
42, # x is 7, x%4 is 3, so g(x) becomes (lambda x:42)(7) or 42
8, # x is 8, x%4 is 0, so g(x) becomes (lambda x:x*1)(8) or 8*1
81, # x is 9, x%4 is 1, so g(x) becomes (lambda x:x*x)(9) or 9*9
1000, # x is 10, x%4 is 2, so g(x) becomes (lambda x:x*x*x)(10) or 10*10*10
42 # x is 11, x%4 is 3, so g(x) becomes (lambda x:42)(11) or 42
]
基本的に、引数として を使用g(x)
してリスト内の関数の 1 つを呼び出しますx
。リスト内包表記でxrange
呼び出すと、関数が循環し、4 回ごとの呼び出しは同じ関数になります。
これは Python の理解を助けるための単なる演習であることはわかっていますが、4 つの関数すべてが を呼び出すたびに再作成されるため、これは恐ろしく非効率的なコードであることに注意してくださいg()
。実際にこの動作が必要な場合は、いくつかのステートメントdef
を含む関数を作成する方がよいでしょう (コードが読みやすくなります)。if
何が起こっているのかをよりよく理解するためにこれを行います(さらに説明が必要な場合はコメントを残してください)
In [44]: g = lambda x:[lambda x:x*1, lambda x:x*x, lambda x:x*x*x, lambda x:42][x%4](x)
In [45]: {x:g(x) for x in xrange(12)}
Out[45]:
{0: 0,
1: 1,
2: 8,
3: 42,
4: 4,
5: 25,
6: 216,
7: 42,
8: 8,
9: 81,
10: 1000,
11: 42}