如何在保留时合并2个任意未排序列表a
和b
这两个清单的顺序?我不想丢弃重复或排序。
格式化空白只是为了让人类读者可视化:
a = ['a', 'b', 'c', 'X', 'Y', '127' ]
b = ['a', 'b', 'X', '44', 'Y', 'w', '127', 'X' ]
所需输出m
:
m = ['a', 'b', 'c', 'X', '44', 'Y', 'w', '127', 'X' ]
我应该更简洁地指定合并顺序。
匹配优先级列在a
列表中:
尝试将列表a
中的每个项目与b
So if a = ['b', 'a', 'r', 'n']
and b = ['b', 'r', 'a', 'n'],
merged m = ['b', 'r', 'a', 'r', 'n']
字典解决方案删除重复项(b[2]
和b[7]
都是'X'
)。
这需要是程序化的;我正在查看数百万行数据。 difflib
很有意思,可能是另一个问题,但我认为这对这个问题没有帮助。
我在Windows-7上使用Python 2.7.12
下面的代码解决了这个问题,但它并不像我想的那样干净简单。
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()
答案 0 :(得分:3)
您可以使用difflib
,但您必须自己进行合并。这可能很棘手 - 并且使用计算机并不容易(考虑到必须在版本控制系统中手动合并冲突时)。但是,很多情况可以自动处理。
这里有一些代码可以帮助您入门 - 我不保证它适用于所有情况,所以如果您找到了改进,请随时告诉我,我会尝试编辑它们:
a = ['a', 'b', 'c', 'X', 'Y', '127' ]
b = ['a', 'b', 'X', '44', 'Y', 'w', '127', 'X' ]
import difflib
matches = difflib.SequenceMatcher(a=a, b=b).get_matching_blocks()
# Pointers to locations in the `a` and `b` lists to keep track of our progress.
ix_a = 0
ix_b = 0
c = []
for match in matches:
# Add in missing elements from `a` -- Assume `a` comes first?
if match.a > ix_a:
c.extend(a[ix_a: match.a])
# add in missing elements from `b`
if match.b > ix_b:
c.extend(b[ix_b: match.b])
# add in common elements.
part = a[match.a:match.a + match.size]
c.extend(part)
# update our pointers into the original sequences.
ix_a = match.a + match.size
ix_b = match.b + match.size
print(c)
显然,你有点依赖于difflib
选择匹配数据中的运行的方式。例如@ZeroPiraeus指出的示例:('barn'
和'bran'
) 1 会产生'brarn'
,但如果您反转输入的顺序'baran'
。
这里令人惊讶的是,这两个结果并不相同 - 事实上,如果你改变输入的顺序,期望它们有不同的排序是很自然的。但是,它可能令人惊讶它们具有完全不同的值(一个有两个'r'
而另一个有两个'a'
。)
1 我为了简洁起见将这些列表格式化为字符串。
答案 1 :(得分:1)
由于指定了问题,因此没有单一的正确结果。例如:
a = ['b', 'r', 'a', 'n']
b = ['b', 'a', 'r', 'n']
m = ['b', 'a', 'r', 'a', 'n']
a = ['b', 'r', 'a', 'n']
b = ['b', 'a', 'r', 'n']
m = ['b', 'r', 'a', 'r', 'n']