我有两个已经排序的列表。我需要离开外部加入他们。以下代码完成了工作:
left_sorted_list = [1, 2, 3, 4, 5]
right_sorted_list = [[2, 21], [4, 45], [6, 67]]
right_dict = {r[0]: r[1] for r in right_sorted_list}
left_outer_join = [[l, right_dict[l] if l in right_dict.keys() else None]
for l in left_sorted_list]
print(left_outer_join)
[[1, None], [2, 21], [3, None], [4, 45], [5, None]]
但是,我不确定这种方法是否非常有效。是否有更有效的方法来利用正确列表已经排序的事实,而不编写循环?
修改我加入的密钥在左侧和右侧列表中都是唯一的。
答案 0 :(得分:4)
这是一个内存效率高的版本,可以一次生成一个键/值对:
def left_outer_join(keys, pairs, default=None):
right = iter(pairs)
right_key = float('-inf') # sentinel: any left key must be larger than it
for left_key in keys:
if left_key == right_key: # *keys* and *right* are in sync
value = right_value # from previous iteration
elif left_key < right_key: # *keys* is behind *right*
value = default
else: # left_key > right_key: *keys* is ahead of *right*
for right_key, right_value in right: # catch up with *keys*
if left_key <= right_key: # drop while left_key > right_key
break
value = right_value if left_key == right_key else default
yield left_key, value
是O(n+m)
单通算法。
示例:
left_sorted_list = [1, 2, 3, 4, 5]
right_sorted_list = [[2, 21], [4, 45], [6, 67]]
print(list(left_outer_join(left_sorted_list, right_sorted_list)))
# -> [(1, None), (2, 21), (3, None), (4, 45), (5, None)]
keys
和pairs
可以是相应的键和键/值对的无限排序迭代器(例如由heapq.merge()
函数生成)。
答案 1 :(得分:3)
这个答案直接取决于mgilson对OP问题的两条评论。
这并不比你拥有的效率高,但它更具有pythonic。
left_sorted_list = [1, 2, 3, 4, 5]
right_sorted_list = [[2, 21], [4, 45]]
right_dict = dict(right_sorted_list)
left_outer_join = [[l, right_dict.get(l)] for l in left_sorted_list]
就时间复杂度而言,left_sorted_list
和right_sorted_list
每次迭代一次,因此它们都是O(N)。对于字典查找the average look-up is O(1),所以查找所有键也是O(N)。你的时间复杂性不会比现有的好多少。
答案 2 :(得分:1)
对于结果我使用了元组,因此方括号较少;)
left_sorted_list = [1, 2, 3, 4, 5]
right_sorted_list = [[2, 21], [4, 45]]
d = dict(right_sorted_list) # if you have a list of pairs, just pass it to dict()
print [(x, d[x] if x in d else None) for x in left_sorted_list]
## -- End pasted text --
[(1, None), (2, 21), (3, None), (4, 45), (5, None)]