How can I merge 2 arbitrary unsorted lists a
and b
while preserving
the order from both lists? I do not want to discard duplicates or sort.
Formatting of whitespace is just to allow visualization for human readers:
a = ['a', 'b', 'c', 'X', 'Y', '127' ]
b = ['a', 'b', 'X', '44', 'Y', 'w', '127', 'X' ]
Desired output m
:
m = ['a', 'b', 'c', 'X', '44', 'Y', 'w', '127', 'X' ]
I should specify the merge order more concisely.
Matching priority goes to list a
:
Attempt to match every item in list a
to an item in b
So if a = ['b', 'a', 'r', 'n']
and b = ['b', 'r', 'a', 'n'],
merged m = ['b', 'r', 'a', 'r', 'n']
A dictionary solution deletes duplicates (b[2]
and b[7]
both are 'X'
).
This needs to be programmatic; I'm looking at millions of lines of data. difflib
is interesting, possibly for another problem, but I don't think it helps with this one.
I am using Python 2.7.12 on Windows-7
The code below solves this problem, but it is not as clean and simple as I would like.
def merge_lists(a, b):
""" Merge 2 arbitrary unsorted lists a and b while preserving
the order from both lists. Do not discard duplicates or sort."""
ia = ib = 0
m = []
if len(a) == 0:
m = b
elif len(b) == 0:
m = a
while ia < len(a) and ib < len(b):
if a[ia] == b[ib]:
m.append(a[ia])
ia += 1
ib += 1
else:
count = b[ib:].count(a[ia])
if count == 0:
m.append(a[ia])
ia += 1
else:
k = b[ib:].index(a[ia])
for i in range(ib, k+ib):
m.append(b[i])
ib += k
if ia >= len(a):
for i in range(ib, len(b)):
m.append(b[i])
if ib >= len(b):
for i in range(ia, len(a)):
m.append(a[i])
return m #--- END --- merge_lists()