2012-02-09 17 views
0

誰かが親切に次のようなpythonコードがどのように動いているのか説明できますか?このコードは、3タプルとして配列された一連の整数を読み込みます。pythonのマップを使って整数のシーケンスを読む

inverted_list = map(lambda i: (int(numbers[2 + 3*i]), 
          float(numbers[3 + 3*i]), 
          float(numbers[4 + 3*i])) 
        ,range(0, (len(numbers) - 2)/3)) 

マップとラムダの動作はまったく同じですか?ラムダは本当にここで必要ですか?

ありがとうございました。

答えて

1

いいえ、ラムダは本当にここに必要とされていない、リスト内包よりも少し遅く実行されます、これはのように書くこともできます。

inverted_list = [(int(numbers[2 + 3*i]), 
        float(numbers[3 + 3*i]), 
        float(numbers[4 + 3*i])) for i in range(0, (len(numbers) - 2)/3] 

私は私が今日だけコーヒーの私の最初のカップによ以来、インデクサーの数学のビットに入るが、何ありませんよは、シーケンスに関数を適用し、各要素の関数の結果を含む新しいシーケンスを生成します。 lambdaは関数で、この場合は数値からタプルを作成します。シーケンスはrange式で、インデックス式で使用できるiの値のリスト(例:3 + 3*i)が表示されます。

あなたのコードスニペットのバージョン@gnibblerと私はモダン pythonです。これは、Python 1.5のようなものではありませんでした。そこで、mapreducezipなどの「機能的な」上位演算を使用しました。私は個人的にはたくさん好きですが、ほとんどのタスクで置き換えられてしまうのではないかと思います。リスト内包はこのようなケースではより表現力豊かです!

range(0, (len(numbers) - 2)/3) 

ラムダとのタプルへ:

1

これは、このリストの理解とほぼ同じです。あなたはどこにでもしかしi 3を掛けたい理由

inverted_list = [((int(numbers[2 + 3*i]), float(numbers[3 + 3*i]), 
       float(numbers[4 + 3*i])) for i in range(0, (len(numbers) - 2)/3)] 

が私を打つのにラムダでマップを使用すると、

inverted_list = [((int(numbers[i]), float(numbers[1+i]), 
       float(numbers[2+i])) for i in range(2, len(numbers), 3)] 
+0

これは、最初の2つの数字がシーケンスの一部ではないためです。私はそれがシリーズの第3要素から始まってループを効果的に実行していると思います。私はマップ/ラムダがここで他の操作を実行しているかどうか、それをちょうど混乱させました。 –

1

それは範囲をマッピングリスト

(numbers[2],numbers[3], numbers[4], numbers[2 + 3],numbers[3 + 3], numbers[4 + 3], ...., numbers[2 + 3*((len(numbers) -2)/3)],numbers[3 + 3*((len(numbers) -2)/3)], numbers[4 + 3*((len(numbers) -2)/3)] 

を作成します。

一つの方法は、サイズ3ステップで2から始まるリストの内包と反復の範囲を使用することです:

[(int(numbers[i]), float(numbers[i + 1]), float(numbers[i + 2])) for i in range(2,len(numbers), 3)] 
1

あなたはすでにこれを表現するためのよりよいまたはより近代的な方法を説明する答えを持っていますが、私はしたいと思いますより基本的な機能の点でラムダとマップが果たす役割を正確に示します。まず、ここにあなたの例があります:

inverted_list = map(lambda i: (int(numbers[2 + 3*i]), 
           float(numbers[3 + 3*i]), 
           float(numbers[4 + 3*i])) 
        ,range(0, (len(numbers) - 2)/3)) 

少し明確にするために、私はマップする引数を分けます。これは同等です。

func = lambda i:(int(numbers[2 + 3*i]), 
       float(numbers[3 + 3*i]), 
       float(numbers[4 + 3*i])) 
sequence = range(0, (len(numbers) - 2)/3) 
inverted_list = map(func, sequence) 

lambdaは、単に式の中の単純な機能を表現する方法である:私が変更されたすべてのは、別の文でマッピングするために、引数のそれぞれを計算することです。私たちは、効果を変更することなく、通常の関数でそれを置き換えることができます。

def func(i): 
    return (int(numbers[2 + 3*i]), 
      float(numbers[3 + 3*i]), 
      float(numbers[4 + 3*i])) 
sequence = range(0, (len(numbers) - 2)/3) 
inverted_list = map(func, sequence) 

mapは「高階関数」、引数として別の関数を取る関数と呼ばれるものです。 sequenceの各項目によるmap意志ループ、引数としてその項目にfuncを呼び出して、どんな機能のリターンを取り、新しいリストに追加します。*

あなたは高階関数や発電機なしで同じことをやってみたかった場合ラムダの利点は、あなたが一つの式で特に一時変数を導入し、おそらくいくつかの方法であなたがしたいポイントの前に関数を宣言する必要が何かを表現することができるということです

def func(i): 
    return (int(numbers[2 + 3*i]), 
      float(numbers[3 + 3*i]), 
      float(numbers[4 + 3*i])) 
sequence = range(0, (len(numbers) - 2)/3) 
inverted_list = [] 
for item in sequence: 
    inverted_list.append(func(item)) 

:表現、あなたは長い道のりをこれを書くことができますそれを使用する。 mapのメリットは、同様に、一時変数とループを必要とするものを1つの式で記述できることです。

(*)mapはPython 3から実際にはリストではなくイテレータを返します。

関連する問題