2016-12-21 12 views
0

を結合:RDDの作成と変数私は非常に単純なコード持って

[(0, 0), (1, 0), (2, 0), (3, 0), (4, 0), (5, 1), (6, 1), (7, 1), (8, 1), (9, 1)] 

ただし、出力は以下の通りです:

def fun(x, n): 
    return (x, n) 

rdds = [] 
for i in range(2): 
    rdd = sc.parallelize(range(5*i, 5*(i+1))) 
    rdd = rdd.map(lambda x: fun(x, i)) 
    rdds.append(rdd) 

a = sc.union(rdds) 
print a.collect() 

を私は、出力は次のことを予想していました

[(0, 1), (1, 1), (2, 1), (3, 1), (4, 1), (5, 1), (6, 1), (7, 1), (8, 1), (9, 1)] 

これは、少なくとも言わないと驚異的です。

それは(forループの最後の実行から)1であるcollect()が呼び出されたとき、それはクマ1は、ある原因RDDS、RDDSを作成するために使用されているiの値の遅延評価に、そうです。

ここで、タプルの両方の要素は、iから派生しています。

しかし、それはそうです、タプルの最初の要素のために、iクマはタプルiの2番目の要素は0と1の間の値値2.

を負う誰かが何が起こっているのか説明していただけますか?

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

答えて

2

だけで、なぜ、このような場合は、この

https://docs.python.org/2.7/tutorial/controlflow.html#default-argument-values

+0

'i = i'は' i'をラムダ関数のスコープにプッシュし、呼び出されるとラムダ関数のローカル値が最初にアクセスされます。 – MYGz

+0

@MohammadYusufGhaziはい。デフォルト値は、定義スコープの関数定義時点で評価されます。 –

+0

'range(2) 'によって生成された' list'の '0'と' 1'の整数オブジェクトがラムダ関数の引数に割り当てられます。そのリスト内の項目はまだ他の変数によって指し示されているので、そのリストはガベージコレクションされません。 – MYGz

0

sc.parallelize()は即座に実行されるアクションです。したがって、iの値、すなわち01の両方の値が使用されます。

rdd.map()の場合は、collect()に後で電話するときには、最後の値がiになります。

ここ
rdd = sc.parallelize(range(5*i, 5*(i+1))) 
rdd = rdd.map(lambda x: fun(x, i)) 

rdd.map文句を言わないRDDを変換、それだけでDAG(有向非巡回グラフ)を作成します、すなわちラムダ関数は、RDDの要素に適用されることはありません。

あなたが収集()を呼び出すと、その後、ラムダ関数が呼び出されますが、あなたはiのその値が使用されます、その後収集呼び出す前i=10を再割り当てする場合、その時点でiが1の値を持ちます。

+0

を見て、唯一のPythonについてです

rdd = rdd.map(lambda x, i=i: (x, i)) 

rdd = rdd.map(lambda x: fun(x, i)) 

を変更値です0と1はタプルの最初の要素に使用されますが、私の例では2番目の要素は1だけです。ありがとう。 – abhinavkulkarni

+1

@abhinavkulkarni sc.parallelize()は、rdd.map()が変換である間に即座に実行されるアクションであるためです。ループ内でrddを収集してリストに追加すると、目的の結果が得られます。 – MYGz

+0

@abhinavkulkarniあなたはzhangtongの解を取って、ラムダ関数のスコープに 'i'の値を送ります。したがって、ラムダ関数が呼び出されると、 'i'の値が変更された外側スコープに登る前に、' i'のローカル値を最初に使用します。 – MYGz

関連する問題