我有两个像这样的数组:
[('a', 'beta'), ('b', 'alpha'), ('c', 'beta'), .. ]
[('b', 37), ('c', 22), ('j', 93), .. ]
我想制作类似的东西:
[('b', 'alpha', 37), ('c', 'beta', 22), .. ]
有一种简单的方法吗?
答案 0 :(得分:1)
没有内置方法。我假设添加类似numpy
的包将提供额外的功能。
但是如果你想在不使用任何额外包的情况下解决它,你可以像这样使用一个衬里:
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)]
答案 1 :(得分: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)]
这比O(n + m)更接近于O(nm)的复杂度更低,因为它避免了计算product(l,r)
,然后像天真的方法那样进行过滤。
主要来自:Fritz 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)
。