Недавно я столкнулся с подобной проблемой при реализации функции. Сначала я попытался четко определить постановку проблемы. Если я правильно понимаю, вот описание проблемы
Постановка задачи
Напишите функцию merge_lists, которая объединит список списков с перекрывающимися элементами, сохраняя при этом порядок элементов.
Ограничения
-
Если элемент A находится перед элементом B во всех списках, где они встречаются вместе, то элемент A должен предшествовать пункту B в конечном списке также
-
Если порядок обмена A и пункт B в разных списках, то есть в некоторых списках A предшествует B, а в некоторых других B предшествует A, тогда порядок A и B в конечном списке должен быть таким же, как и их порядок в первом списке, где они встречаются вместе. То есть, если A предшествует B в l1 и B предшествует A в l2, тогда A должен предшествовать B в конечном списке
-
Если элементы A и элемент B не встречаются вместе в любом списке, их порядок должен определяться положением списка, в котором каждый из них встречается первым. То есть, если элемент A находится в l1 и l3, элемент B находится в l2 и l6, тогда порядок в конечном списке должен быть A, а затем B
Тестовый кейс 1:
Входные данные:
l1 = [«Тип и размер», «Ориентация», «Материал», «Местоположения», «Тип передней печати», «Обратный тип печати»]
l2 = [«Тип и размер», «Материал», «Местоположения», «Тип передней печати», «Размер передней печати», «Обратный тип печати», «Назад размер печати»]
l3 = ["Ориентация", "Материал", "Местоположения", "Цвет", "Тип передней печати"]
merge_lists ([l1, l2, l3])
Вывод:
[«Тип и размер», «Ориентация», «Материал», «Местоположения», «Цвет», «Тип передней печати», «Размер передней печати», «Обратный тип печати», «Назад размер печати»]
Тестовый пример 2:
Входные данные:
l1 = ["T", "V", "U", "B", "C", "I", "N"]
l2 = ["Y", "V", "U", "G", "B", "I"]
l3 = ["X", "T", "V", "M", "B", "C", "I"]
l4 = ["U", "P", "G"]
merge_lists ([l1, l2, l3, l4])
Вывод:
['Y', 'X', 'T', 'V', 'U', 'M', 'P', 'G', 'B', 'C', 'I', 'N']
Тестовый кейс 3:
Входные данные:
l1 = ["T", "V", "U", "B", "C", "I", "N"]
l2 = ["Y", "U", "V", "G", "B", "I"]
l3 = ["X", "T", "V", "M", "I", "C", "B"]
l4 = ["U", "P", "G"]
merge_lists ([l1, l2, l3, l4])
Вывод:
['Y', 'X', 'T', 'V', 'U', 'M', 'P', 'G', 'B', 'C', 'I', 'N']
Решение
I arrived at a reasonable Решение which solved it correctly for all the data I had. (It might be wrong for some other data set. Will leave it for others to comment that). Here is the Решение
def remove_duplicates(l):
return list(set(l))
def flatten(list_of_lists):
return [item for sublist in list_of_lists for item in sublist]
def difference(list1, list2):
result = []
for item in list1:
if item not in list2:
result.append(item)
return result
def preceding_items_list(l, item):
if item not in l:
return []
return l[:l.index(item)]
def merge_lists(list_of_lists):
final_list = []
item_predecessors = {}
unique_items = remove_duplicates(flatten(list_of_lists))
item_priorities = {}
for item in unique_items:
preceding_items = remove_duplicates(flatten([preceding_items_list(l, item) for l in list_of_lists]))
for p_item in preceding_items:
if p_item in item_predecessors and item in item_predecessors[p_item]:
preceding_items.remove(p_item)
item_predecessors[item] = preceding_items
print "Item predecessors ", item_predecessors
items_to_be_checked = difference(unique_items, item_priorities.keys())
loop_ctr = -1
while len(items_to_be_checked) > 0:
loop_ctr += 1
print "Starting loop {0}".format(loop_ctr)
print "items to be checked ", items_to_be_checked
for item in items_to_be_checked:
predecessors = item_predecessors[item]
if len(predecessors) == 0:
item_priorities[item] = 0
else:
if all(pred in item_priorities for pred in predecessors):
item_priorities[item] = max([item_priorities[p] for p in predecessors]) + 1
print "item_priorities at end of loop ", item_priorities
items_to_be_checked = difference(unique_items, item_priorities.keys())
print "items to be checked at end of loop ", items_to_be_checked
print
final_list = sorted(unique_items, key=lambda item: item_priorities[item])
return final_list
Я также открыл исходный код как часть библиотеки с именем toolspy. Таким образом, вы можете просто сделать это
pip install toolspy
from toolspy import merge_lists
lls=[['a', 'x', 'g'], ['x', 'v', 'g'], ['b', 'a', 'c', 'x']]
merge_lists(lls)