Python:返回列表中依次出现的共同项和不同项的列表

3
lists = [[a,b,c,d],[a,b,c,d,e],[a,b,c,x],[a,b,c,d,e,f]....lots]

common_items = [a,b,c]
uncommon_items = [[d], [d,e], [x], [d,e,f]]

common_elements(lists[0],lists[1])

def common_elements(list1, list2):
    return [element for element in list1 if element in list2]

许多SO上的答案只能同时处理两个列表。我们需要一个可以处理任意数量的列表并返回两个列表的方法。

注意:列表的顺序很重要,因此不包括集合。 注意:必须是每个列表中的最低公共项,而不是基于列表中的第一个列表。


1
你目前的代码是什么? - Scott Hunter
3个回答

3
最简单的方法是使用集合,但您将失去排序。
lists = [['a','b','c','d'],
         ['a','b','c','d','e'],
         ['a','b','c','x'],
         ['a','b','c','d','e','f']]

sets = map(set, lists)
common = set.intersection(*sets)
uncommon = [s-common for s in sets]
print common    # set(['a', 'c', 'b'])
print uncommon  # [set(['d']), set(['e', 'd']), set(['x']), set(['e', 'd', 'f'])]

集合是表示共同元素的最佳方式。您可以通过使用不同的列表推导来维护不常见元素的顺序。

uncommon = [[x for x in l if x not in common] for l in lists]
print uncommon  # [['d'], ['d', 'e'], ['x'], ['d', 'e', 'f']]

假设在所有的列表中,common 中的元素出现的顺序相同,那么你可以将这个共同的集合转化为一个列表。
common = [x for x in lists[0] if x in common]

对我来说,顺序很重要。 - I Love Python
常见的排序也很重要。 - I Love Python
由于lists都保持顺序,返回结果的顺序很重要。 - I Love Python
这个好像没有返回最小公共元素。例如,它给了我[a,b,c,d]作为公共元素,而应该是[a,b,c]。 - I Love Python
它给了我正确的输出。请确保您正在使用与我相同的输入数据。 - Tim
显示剩余6条评论

1
这个解决方案也保留了顺序。
common, uncommon = lists[0], lists[0]
for clist in lists:
    common = [item for item in common if item in clist]
uncommon = [[item for item in clist if item not in common] for clist in lists ]
print common, uncommon

输出

['a', 'b', 'c'] [['d'], ['d', 'e'], ['x'], ['d', 'e', 'f']]

根据OP在评论中的要求,以下是编辑内容:
common = lists[0]
from itertools import takewhile
for l1, l2 in zip(lists, lists[1:]):
    common = [i[0] for i in takewhile(lambda i: i[0] == i[1] == i[2], zip(l1, l2, common))]
uncommon = [clist[len(common):] for clist in lists]
print common, uncommon

非常好,但与先前的答案相同,它似乎没有返回最低公共元素。例如,它给我 [a,b,c,d] 作为共同元素,而它应该是 [a,b,c]。 - I Love Python
@ILovePython 对于你在问题中提供的输入数据,它只返回 ['a', 'b', 'c'] - thefourtheye
尝试这个:[['a', 'b', 'c', 'c', 'd'], ['a', 'b', 'c', 'd', 'd', 'e', 'f']] - I Love Python
返回 `>>> lists = [['a', 'b', 'c', 'c', 'd'], ['a', 'b', 'c', 'd', 'd', 'e', 'f']]
gen_lowest_common_items(lists) [['a', 'b', 'c', 'c', 'd'], ['a', 'b', 'c', 'd', 'd', 'e', 'f']] a,b,c,c,d 不是以那个顺序出现的最低公共项。顺序很重要,我期望得到 a,b,c
- I Love Python
@ILovePython 终于明白你的意思了。现在请检查我的答案。 - thefourtheye

0

好的,我会这样做...

代码:

def lcs(l,key=None):
    if key==None: key=min(l,key=len)
    t = [x for x in l if key in x]
    return key if t == l else lcs(l,key[:-1])

if __name__=='__main__':
    lists = [['a','b','c','d'],
             ['a','b','c','d','e'],
             ['a','b','c','x'],
             ['a','b','c','d','e','f']]

    l = [''.join(item) for item in lists]
    print lcs(l)  

输出:

abc  

我对复杂度等方面不是很了解,但这段代码可以解决问题。

希望能有所帮助 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接