У меня есть два списка, скажем так:
keys1 = ['A', 'B', 'C', 'D', 'E', 'H', 'I']
keys2 = ['A', 'B', 'E', 'F', 'G', 'H', 'J', 'K']
Как создать объединенный список без дубликатов, которые сохраняют порядок обоих списков, вставляя отсутствующие элементы туда, где они принадлежат? Вот так:
merged = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K']
Обратите внимание, что элементы можно сравнивать с равенством, но не упорядочивать (это сложные строки). Элементы нельзя упорядочить, сравнивая их, но они имеют порядок, основанный на их появлении в исходных списках.
В случае противоречия (различный порядок в обоих входных списках) любой вывод, содержащий все элементы, действителен. Конечно, с бонусными баллами, если решение показывает "здравый смысл" в сохранении большей части заказа.
Снова (поскольку некоторые комментарии все еще спорят об этом), списки обычно не противоречат друг другу с точки зрения порядка общих элементов. В этом случае алгоритм должен корректно обработать эту ошибку.
Я начал с версии, которая перебирает списки с помощью .next(), чтобы продвигать только список, содержащий несопоставимые элементы, но .next() просто не знает, когда остановиться.
merged = []
L = iter(keys1)
H = iter(keys2)
l = L.next()
h = H.next()
for i in range(max(len(keys1, keys2))):
if l == h:
if l not in merged:
merged.append(l)
l = L.next()
h = H.next()
elif l not in keys2:
if l not in merged:
merged.append(l)
l = L.next()
elif h not in keys1:
if h not in merged:
merged.append(h)
h = H.next()
else: # just in case the input is badly ordered
if l not in merged:
merged.append(l)
l = L.next()
if h not in merged:
merged.append(h)
h = H.next()
print merged
Это, очевидно, не работает, так как .next() вызовет исключение для самого короткого списка. Теперь я могу обновлять свой код, чтобы перехватывать это исключение каждый раз, когда я вызываю .next(). Но код уже довольно непитоничен, и это явно лопнуло бы.
Кто-нибудь имеет лучшее представление о том, как перебрать эти списки, чтобы объединить элементы?
Бонусные баллы, если я могу сделать это для трех списков за один раз.