def get_max(r, a, b):
""" Returns the maximum value in the form (index, value). """
return max([(x+a, r[a:b][x]) for x in xrange(len(r[a:b]))], key=lambda x:x[1])
このリスト内包表記が何をするのか説明できる人はいますか?
def get_max(r, a, b):
""" Returns the maximum value in the form (index, value). """
return max([(x+a, r[a:b][x]) for x in xrange(len(r[a:b]))], key=lambda x:x[1])
このリスト内包表記が何をするのか説明できる人はいますか?
バラバラに分解してみましょう。
まず、これは listcomp だけです:
[(x+a, r[a:b][x]) for x in xrange(len(r[a:b]))]
これは、次のループと同等です。
result=[]
for x in xrange(len(r[a:b])):
result.append((x+a, r[a:b][x]))
では、各パーツは何をするのでしょうか?
r[a:b]
r
インデックス a (含む) から b (含まない) までのサブシーケンスです。len(r[a:b])
というのはほとんど派手な言い方ですが、b-a
完全ではありません。なぜならb
、シーケンスの終わりを過ぎている可能性があるか、インデックスのいずれかが負のインデックスである可能性があるからです。そしてxrange(len(r[a:b]))
、0からその長さまでのすべての数字です(これも排他的です)。
x
ここで、 0 からその長さまでのこれらの数値のそれぞれについて、tuple を作成します(x+a, r[a:b][x])
。
例を見てみましょう:
>>> r = ['a', 'b', 'c', 'd', 'e', 'f']
>>> a = 2
>>> b = 4
>>> r[a:b]
['c', 'd']
>>> len(r[a:b])
2
>>> list(xrange(len(r[a:b])))
[0, 1]
>>> x=0
>>> (x+a, r[a:b][x])
(2, 'c')
>>> x = 1
>>> (x+a, r[a:b][x])
(3, 'd')
ご覧のとおり、次のように からa
までのインデックスの (インデックス, 値) のリストを作成しています。b
[(2, 'c'), (3, 'd')]
同じことを書くより良い方法は次のとおりです。
>>> list(enumerate(r))[a:b]
[(2, 'c'), (3, 'd')]
…または…</p>
>>> list(enumerate(r[a:b], a)
[(2, 'c'), (3, 'd')]
r
はシーケンス、a
は開始インデックス、b
は終了インデックスです。リスト内包表記は、(index, r[index])
タプルのリストを提供しa <= index < b
ます。このmax()
呼び出しは、最大値 (タプルの 2 番目の項目) を持つタプルを返します。