Reputation: 357
I want to write a code that can merge list a&b to get list c by filling list a with tuples, of which tuple[0] is none and tuple[1] is the values that are in b but not in a[index][1]. For instance,
a=[(1,None),(2,4),(3,6),(4,None),(5,9)];
b=[4,5,6,7,9]
The desired c should be
c=[(1,None),(2,4),(None,5),(3,6),(4,None),(None,7),(5,9)]
I wrote a simple code as below that appended (None,5) at the end of the list. My actual intention is to insert it as the order of list b (I'm not sure how). Also, it seems to be inefficient as the number of elements in each list grows.
import itertools
a=[(1,None),(2,4),(3,6),(4,None),(5,9)]
b=[4,5,6,7,9]
for elem2 in b:
for elem1 in a:
if elem1[1]==elem2:
#print(str(elem2) +'is in.')
break
else:
a.append((None,elem2))
print(a)
Is there a special function that can achieve the merge?
Upvotes: 4
Views: 1981
Reputation: 114559
If you want to keep the elements ordered by second value then you need to implement a merge operation. The general idea is "keep picking the lower element and add that".
If the elements are sorted also there is no need to use a set
for knowing if an element is present or not:
c = []
ia = ib = 0
while ia < len(a) and ib < len(b):
if a[ia][1] == b[ib]:
# same second element, a wins
c.append(a[ia])
ia += 1
ib += 1
elif a[ia][1] is None or a[ia][1] < b[ib]:
# a element is smaller and comes first
c.append(a[ia])
ia += 1
else:
# b element is smaller and comes first
v.append((None, b[ib]))
ib += 1
# at the end may be there are extra a elements, add all of them at once
if ia < len(a):
c += a[ia:]
# or there may be extra b elements
while ib < len(b):
c.append((None, b[ib:]))
ib += 1
Upvotes: 1
Reputation: 23119
Here's a solution that works. It could likely be done more elegantly, but I'm pretty sure it works for any input values, making only a single pass:
a = [(1, None), (2, 4), (3, 6)]
b = [4, 5, 6]
i = 1
while True:
if i == len(a):
for v in b:
a.append((None, v))
break
while len(b) and a[i][1] >= b[0]:
v = b.pop(0)
if a[i][1] > v:
a.insert(i, (None, v))
i += 1
i += 1
print(a)
Result:
[(1, None), (2, 4), (None, 5), (3, 6)]
Tried it with more input too:
b = [4, 5, 6, 7, 8, 9, 10]
which gives you:
[(1, None), (2, 4), (None, 5), (None, 6), (None, 7), (3, 8), (None, 9), (None, 10)]
Upvotes: 0