我的代码:
def merge_join(self, outer, outer_join_index, inner, inner_join_index):
a=list(inner)
b=list(outer)
if not a or not b:
return
inner_copy = sorted(a,key=lambda tup: tup[inner_join_index])
outer_copy = sorted(b,key=lambda tup: tup[outer_join_index])
inner_counter=0
outer_counter=0
while inner_counter < len(inner_copy) and outer_counter < len(outer_copy):
if outer_copy[outer_counter][outer_join_index]==inner_copy[inner_counter][inner_join_index]:
yield outer_copy[outer_counter]+inner_copy[inner_counter]
outer_counter+=1
elif outer_copy[outer_counter][outer_join_index]<inner_copy[inner_counter][inner_join_index]:
outer_counter+=1
else:
inner_counter+=1
其中 outer 和 inner 是生成器。
我为算法运行了一个给定的测试,但它返回了一个包含 127 个元素的生成器,而不是预期的 214 个元素。任何人都可以帮我检查我的代码中可能存在错误的位置吗?谢谢!!
最佳答案
如果你想为每个 inner
行选择一个正确的 outer
行(在 inner
中没有重复并且如果没有匹配则跳过行如果匹配,你应该增加 inner_counter
,而不是像你正在做的那样 outer_counter
。
原因是,否则如果多个内部行具有相同的值,您将只输出其中的第一个。
如果你想做一个完整的连接(从 inner
和 outer
为连接列的给定值生成行的所有笛卡尔积)那么这有用类似的东西明确编码
while inner_counter < len(inner_copy) and outer_counter < len(outer_copy):
key = min(inner_copy[inner_index][inner_join_index],
outer_copy[outer_index][outer_join_index])
inner_group = []
while inner_index < len(inner) and key == inner_copy[inner_index][inner_join_index]:
inner_group.append(inner_copy[inner_index])
inner_index += 1
outer_group = []
while outer_index < len(outer) and key == outer_copy[outer_index][outer_join_index]:
outer_group.append(outer_copy[outer_index])
outer_index += 1
# Here you can handle left or right join by replacing an
# empty group with a group of one empty row (None,)*len(row)
for i in inner_group:
for o in outer_group:
yield i + o
关于python - Python 中的排序-合并-连接算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35251155/