给定两个输入列表,如何创建两个输入共用的元素列表?

例如:对于输入[1,2,3,4,5,6]和[3,5,7,9],结果应该是[3,5];输入[‘这个’,‘这’,' n ', ', ']和[‘这个’,‘不’,‘,’,','],结果应该[‘这个’,‘,’]。


参见: 在Python中,如何从两个列表中找到常用词,同时保持词序?(维持秩序) Python -多个列表的交集?(用于计算>= 3个列表之间的交集) 两个包含重复项的列表的交集?(保持重复元素)


当前回答

您还可以使用集合并在一行中获得共性:从其中一个集合中减去包含差异的集合。

A = [1,2,3,4]
B = [2,4,7,8]
commonalities = set(A) - (set(A) - set(B))

其他回答

您还可以使用集合并在一行中获得共性:从其中一个集合中减去包含差异的集合。

A = [1,2,3,4]
B = [2,4,7,8]
commonalities = set(A) - (set(A) - set(B))

你可以使用numpy来解决这个问题:

import numpy as np

list1 = [1, 2, 3, 4, 5, 6]
list2 = [3, 5, 7, 9]

common_elements = np.intersect1d(list1, list2)
print(common_elements)

Common_elements将是numpy数组:[3 5]。

我已经制定出了深度交叉口的完整解决方案

def common_items_dict(d1, d2, use_set_for_list_commons=True, use_set_for_dict_key_commons=True, append_empty=False):
    result = {}
    if use_set_for_dict_key_commons:
        shared_keys=list(set(d1.keys()).intersection(d2.keys())) # faster, order not preserved
    else:
        shared_keys=common_items_list(d1.keys(), d2.keys(), use_set_for_list_commons=False)

    for k in  shared_keys:
        v1 = d1[k]
        v2 = d2[k]
        if isinstance(v1, dict) and isinstance(v2, dict):
            result_dict=common_items_dict(v1, v2, use_set_for_list_commons, use_set_for_dict_key_commons, append_empty)
            if len(result_dict)>0 or append_empty:
                result[k] = result_dict 
        elif isinstance(v1, list) and isinstance(v2, list):
            result_list=common_items_list(v1, v2, use_set_for_list_commons, use_set_for_dict_key_commons, append_empty)
            if len(result_list)>0 or append_empty:
                result[k] = result_list 
        elif v1 == v2:
            result[k] = v1
    return result

def common_items_list(d1, d2, use_set_for_list_commons=True, use_set_for_dict_key_commons=True, append_empty=False):
    if use_set_for_list_commons: 
        result_list= list(set(d2).intersection(d1)) # faster, order not preserved, support only simple data types in list values
        return result_list

    result = []
    for v1 in d1: 
        for v2 in d2:
            if isinstance(v1, dict) and isinstance(v2, dict):
                result_dict=common_items_dict(v1, v2, use_set_for_list_commons, use_set_for_dict_key_commons, append_empty)
                if len(result_dict)>0 or append_empty:
                    result.append(result_dict)
            elif isinstance(v1, list) and isinstance(v2, list):
                result_list=common_items_list(v1, v2, use_set_for_list_commons, use_set_for_dict_key_commons, append_empty)
                if len(result_list)>0 or append_empty:
                    result.append(result_list)
            elif v1 == v2:
                result.append(v1)
    return result


def deep_commons(v1,v2, use_set_for_list_commons=True, use_set_for_dict_key_commons=True, append_empty=False):
    """
    deep_commons
     returns intersection of items of dict and list combinations recursively

    this function is a starter function, 
    i.e. if you know that the initial input is always dict then you can use common_items_dict directly
    or if it is a list you can use common_items_list directly

    v1 - dict/list/simple_value
    v2 - dict/list/simple_value
    use_set_for_dict_key_commons - bool - using set is faster, dict key order is not preserved 
    use_set_for_list_commons - bool - using set is faster, list values order not preserved, support only simple data types in list values
    append_empty - bool - if there is a common key, but no common items in value of key , if True it keeps the key with an empty list of dict

    """

    if isinstance(v1, dict) and isinstance(v2, dict):
        return common_items_dict(v1, v2, use_set_for_list_commons, use_set_for_dict_key_commons, append_empty)
    elif isinstance(v1, list) and isinstance(v2, list):
        return common_items_list(v1, v2, use_set_for_list_commons, use_set_for_dict_key_commons, append_empty)
    elif v1 == v2:
        return v1
    else:
        return None


needed_services={'group1':['item1','item2'],'group3':['item1','item2']}
needed_services2={'group1':['item1','item2'],'group3':['item1','item2']}

result=deep_commons(needed_services,needed_services2)

print(result)

前面的答案都可以找到唯一的公共元素,但不能解释列表中重复的项目。如果你想让公共元素在列表中以相同的数字出现,你可以使用下面的一行代码:

l2, common = l2[:], [ e for e in l1 if e in l2 and (l2.pop(l2.index(e)) or True)]

或True部分仅在您希望任何元素求值为False时才需要。

S.Mark和SilentGhost建议的解决方案通常会告诉您应该如何以Pythonic方式完成,但我认为您也可以从了解为什么您的解决方案不起作用中受益。问题是,一旦找到两个列表中的第一个公共元素,就只返回该元素。您的解决方案可以通过创建一个结果列表并收集该列表中的公共元素来修复:

def common_elements(list1, list2):
    result = []
    for element in list1:
        if element in list2:
            result.append(element)
    return result

一个使用列表推导式的更简短的版本:

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

然而,正如我所说,这是一种非常低效的方式——Python的内置集类型更高效,因为它们是在C内部实现的。