2017-05-09 5 views
1

私はこのような2列あります。私のようなものを生成したいPythonでSQLスタイルの内部結合?

[('a', 'beta'), ('b', 'alpha'), ('c', 'beta'), .. ] 

[('b', 37), ('c', 22), ('j', 93), .. ] 

[('b', 'alpha', 37), ('c', 'beta', 22), .. ] 

はこれを行う簡単な方法はありますか?

+1

何か試しましたか? – depperm

+0

@depperm私はforループが一致するかどうかをチェックして新しい配列にプッシュすると考えましたが、簡単にできる組み込み関数がいくつかあると思いました。 –

+2

このスレッドをチェック:http://stackoverflow.com/questions/7776907/sql-join-or-rs-merge-function-in-numpy – Cleared

答えて

1

私はハッシュ弁別を示唆しているように参加します方法:中

l = [('a', 'beta'), ('b', 'alpha'), ('c', 'beta')] 
r = [('b', 37), ('c', 22), ('j', 93)] 
d = {} 
for t in l: 
    d.setdefault(t[0], ([],[]))[0].append(t[1:]) 
for t in r: 
    d.setdefault(t[0], ([],[]))[1].append(t[1:]) 
from itertools import product 
ans = [ (k,) + l + r for k,v in d.items() for l,r in product(*v)] 

結果:

[('c', 'beta', 22), ('b', 'alpha', 37)] 

これは、product(l,r)の計算を避けて、単純な方法としてフィルタリングするので、O(n + m)に近いほど複雑さが低くなります。

ほとんどから:差別とフリッツHengleinのリレーショナル代数それはのように書くこともでき加わり、怠惰な製品

def accumulate(it): 
    d = {} 
    for e in it: 
     d.setdefault(e[0], []).append(e[1:]) 
    return d 
l = accumulate([('a', 'beta'), ('b', 'alpha'), ('c', 'beta')]) 
r = accumulate([('b', 37), ('c', 22), ('j', 93)]) 
from itertools import product 
ans = [ (k,) + l + r for k in l&r for l,r in product(l[k], r[k])] 

これは別に両方のリストを蓄積({a:[(b,...)]}[(a,b,...)]をオン)し、その後、そのキーセット間の交差を計算します。これはきれいに見えます。辞書間でl&rがサポートされていない場合は、set(l)&set(r)に置き換えてください。

1

組み込みメソッドはありません。 numpyのようなパッケージを追加すると余分な機能が追加されます。

は、しかし、あなたは余分なパッケージを使用せずに、それを解決したい場合は、次のような1つのライナーを使用することができます。

ar1 = [('a', 'beta'), ('b', 'alpha'), ('c', 'beta')] 
ar2 = [('b', 37), ('c', 22), ('j', 93)] 
final_ar = [tuple(list(i)+[j[1]]) for i in ar1 for j in ar2 if i[0]==j[0]] 
print(final_ar) 

出力:

[('b', 'alpha', 37), ('c', 'beta', 22)]