Библиотека похожа на os.path.commonprefix, но возвращает общий префикс любых 2+ введенных списков?

dict = {'a':['b1','b2', 'b3'], 'b':['b1','b2','b3'], 'c':['b1','b3','b4','b5']}
toList = list(dict.values())
os.path.commonprefix(toList)

os.path.commonprefix(toList) печатает только ['b1'], но я пытаюсь найти самый длинный общий префикс среди всех введенных списков, поэтому здесь ['b1', 'b2']. Другой пример:

[a,b,c],[a,c,c],[a,b] -> [a,b]

[a,c,d],[a,b,c],[a,d] -> [a]


* ОТРЕДАКТИРОВАННЫЙ ИСХОДНЫЙ ВОПРОС - реализованный os.path.commonprefix(toList) не возвращает существующий общий префикс (как в моем примере), но общий префикс всех введенных списков. Есть ли библиотека, которая делает то, что я хочу в моем примере?


person user90823745    schedule 24.01.2019    source источник
comment
Почему вы ожидаете, что ['b1','b2'] будет общим префиксом, если ключ 'c' вместо этого имеет значение, начинающееся с ['b1','b3']?   -  person blhsing    schedule 24.01.2019
comment
@blhsing О, у меня сложилось впечатление, что commonprefix возвращает общий префикс любого из предоставленных списков, думаю, мне нужно найти другой метод, чтобы получить желаемый результат.   -  person user90823745    schedule 24.01.2019
comment
Я запутался - учитывая [a,b,c],[a,c,c],[a,b], почему в результате должно появляться «b», если его нет в [a,c,c] и, следовательно, не является общим для всех трех списков?   -  person jfowkes    schedule 24.01.2019
comment
Это то, что вам нужно of-lists" title="какой питонический способ найти самый длинный общий префикс списка списков"> stackoverflow.com/questions/11263172/   -  person mad_    schedule 24.01.2019
comment
@jfowkes Я хочу вернуть самый длинный общий префикс из любых 2+ списков, поэтому в этом примере самый длинный общий префикс по крайней мере из 2 списков равен [a,b] (в [a,b,c] и [a,b] )   -  person user90823745    schedule 24.01.2019
comment
Таким образом, даже если 2 списка идентичны, как в вашем примере, где 1-й и 2-й списки оба ['b1','b2', 'b3'], вы хотите, чтобы вывод игнорировал последний элемент в списке?   -  person benvc    schedule 24.01.2019
comment
@benvc Я думаю, что способ перебора кода заключается в том, чтобы посмотреть на 1-й элемент во всех списках, если они одинаковы (b1), то посмотреть на следующий элемент во всех списках и сравнить. Если какие-либо 2+ списка все еще одинаковы, продолжайте и верните самый длинный префикс.   -  person user90823745    schedule 24.01.2019


Ответы (2)


Вы можете использовать свой первоначальный подход, добавив itertools в смесь, чтобы найти commonprefix из всех комбинаций списка, а затем использовать max(), чтобы вернуть самую длинную. Обратите внимание, что этот подход вернет только один commonprefix, поэтому, если есть несколько результатов одинаковой длины и длиннее, чем все остальные, он вернет только один из них.

Например:

import itertools
import os

data = [['a','b','c'],['a','c','c'],['a','b']]

prefixes = [os.path.commonprefix([a, b]) for a, b in itertools.combinations(data, 2)]
longest = max(prefixes, key=len)
print(longest)
# OUTPUT
# ['a', 'b']
person benvc    schedule 24.01.2019

Внесены изменения в опубликованный ответ здесь

from itertools import takewhile,izip
x = [['b1', 'b2', 'b3'], ['b1', 'b3', 'b4', 'b5'], ['b1', 'b2', 'b3']]
flag_to_stop=False          # flag to stop returning True 

def allsame(x):
    global flag_to_stop
    if flag_to_stop:
        return False
    elif len(set(x)) == 1:
        return True
    elif len(set(x))>=1 and len(set(x))<len(x):
        flag_to_stop=True   #we have found the maximum common prefix. set flag_to_stop to True
        return True
    elif len(set(x))==len(x):
        flag_to_stop=True
        return False


[i[0] for i in takewhile(allsame ,izip(*x))]

Вывод

['b1', 'b2']
person mad_    schedule 24.01.2019