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

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


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


当前回答

1) Method1 保存list1是字典,然后迭代list2中的每个elem

def findarrayhash(a,b):
    h1={k:1 for k in a}
    for val in b:
        if val in h1:
            print("common found",val)
            del h1[val]
        else:
            print("different found",val)
    for key in h1.iterkeys():
        print ("different found",key)

找到共同和不同的元素:

2) Method2 使用设置

def findarrayset(a,b):
    common = set(a)&set(b)
    diff=set(a)^set(b)
    print list(common)
    print list(diff) 

其他回答

使用Python的集合交集:

>>> list1 = [1,2,3,4,5,6]
>>> list2 = [3, 5, 7, 9]
>>> list(set(list1).intersection(list2))
[3, 5]
list1=[123,324523,5432,311,23]
list2=[2343254,34234,234,322123,123,234,23]
common=[]
def common_elements(list1,list2):
    for x in range(0,len(list1)):
        if list1[x] in list2:
            common.append(list1[x])
            
common_elements(list1,list2)
print(common)

这里有一些解决方案是在O(l1+l2)不计算重复项目,而缓慢的解决方案(至少O(l1*l2),但可能更昂贵)确实考虑重复项目。

所以我想我应该添加一个O(l1*log(l1)+l2*(log(l2))解。如果列表已经排序,这尤其有用。

def common_elems_with_repeats(first_list, second_list):
    first_list = sorted(first_list)
    second_list = sorted(second_list)
    marker_first = 0
    marker_second = 0
    common = []
    while marker_first < len(first_list) and marker_second < len(second_list):
        if(first_list[marker_first] == second_list[marker_second]):
            common.append(first_list[marker_first])
            marker_first +=1
            marker_second +=1
        elif first_list[marker_first] > second_list[marker_second]:
            marker_second += 1
        else:
            marker_first += 1
    return common

另一个更快的解决方案包括从list1创建一个item->计数映射,并遍历list2,同时更新映射和计数。不需要排序。需要额外的内存,但技术上是O(l1+l2)

如果list1和list2是无序的:

使用交叉:

print((set(list1)).intersection(set(list2)))

合并列表并检查元素的出现次数是否大于1:

combined_list = list1 + list2
set([num for num in combined_list if combined_list.count(num) > 1])

类似于上面,但不使用set:

for num in combined_list:
    if combined_list.count(num) > 1:
        print(num)
        combined_list.remove(num)

对于排序列表,没有python特殊的内置,一个O(n)解决方案

p1 = 0
p2 = 0
result = []
while p1 < len(list1) and p2 < len(list2):
    if list1[p1] == list2[p2]:
        result.append(list1[p1])
        p1 += 1
        p2 += 2
    elif list1[p1] > list2[p2]:
        p2 += 1
    else:
        p1 += 1
print(result)

使用集合交叉,set(list1) & set(list2)

>>> def common_elements(list1, list2):
...     return list(set(list1) & set(list2))
...
>>>
>>> common_elements([1,2,3,4,5,6], [3,5,7,9])
[3, 5]
>>>
>>> common_elements(['this','this','n','that'],['this','not','that','that'])
['this', 'that']
>>>
>>>

注意,结果列表可能与原始列表顺序不同。