如何在Python中对两个列表进行异或?

时间:2017-12-27 01:20:54

标签: python python-3.x

我有两个列表,例如:

List<int> nums = new List<int>();

public boolean AddNums(int num){
    if(1<=num&&num<=9&&!nums.Contains(num)){
        nums.Add(num);
        return true;        
    }
    return false;
}

如果我想创建一个仅包含两个元素的第三个列表:

a = ['hello','world']
b = ['hello','world','im','steve']

如果元素的顺序很重要,我该怎么做?我知道我可以使用套装,但他们不断抛弃我的清单。我可以使用c = ['im','steve'] 将它们转换为字符串,但不确定如何以该格式执行此操作。

8 个答案:

答案 0 :(得分:13)

您可以连接列表并使用列表理解:

a = ['hello','world']
b = ['hello','world','im','steve']
final_vals = [i for i in a+b if i not in a or i not in b]

输出:

['im', 'steve']

答案 1 :(得分:9)

选项1:设置方法(推荐)

集合使用symmetric_difference方法,专门返回ab中的元素。订单可以通过列表理解来保留,用于连续列表a + b

comp = set(a).symmetric_difference(b)
[x for x in a + b if x in comp]
# ['im', 'steve']

选项2:pathlib方法

作为参考,另一种区分两个列表的方法可能是使用pathlib.Path.relative_to方法:

import pathlib


p = pathlib.Path(*b)
r = p.relative_to(*a)
list(r.parts)
# ['im', 'steve']

注意:b是较长的列表。此选项的效率可能低于简单列表推导。

答案 2 :(得分:4)

将两个列表一起添加,如果在新列表中显示,则减去交叉点部分。订单保留。

c = a + b
for v in set(a).intersection(set(b)):
    while v in c:
        c.remove(v)

答案 3 :(得分:3)

你也可以创建一个l1来自l2的{​​{3}}元素不存在a = ['hello','world', 'foo'] b = ['hello','world','im','steve'] def difference(l1, l2): return list(filter(lambda x: x not in l2, l1)) print(difference(a, b) + difference(b, a)) # ['foo', 'im', 'steve'] 的函数,并在翻转参数的情况下调用它两次:

filter()

如果您不想使用[item for item in l1 if item not in l2] ,那么这样的简单列表理解也有效:

 {
    "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {},
    "resources": [],
    "outputs": {
        "referenceOutput": {
            "type": "object",
            "value": "[listkeys(resourceId('Microsoft.Web/sites/functions', 'my-function-app','my-function'),'2016-08-01').key]"
        }
    }

答案 4 :(得分:3)

a = ['hello','world']
b = ['hello','world','im','steve']
a = set(a)
b = set(b)
print(a.symmetric_difference(b))

此代码打印仅在其中一个表中的元素。

看这里: https://learnpython.org/en/Sets

答案 5 :(得分:2)

问题确实不是很清楚,而且你可能对@ Ajax1234的answer很好,但这是另一个“接受”。

如果你想比较位置(有点像XOR会做什么),你可以做一些事情,比如获得最短的列表,迭代按位置检查最长列表的位置(检查最长列表中的相同位置是否匹配最短列表中的单词)然后添加剩余部分(最长列表中的“ unwalked ”部分)。如下所示:

a = ['hello', 'world']
b = ['hello', 'world', 'im', 'steve']

min_list = a if len(a) < len(b) else b
max_list = b if len(b) > len(a) else a

results = []
for i, item in enumerate(min_list):
    # Iterate through the shortest list to avoid IndexError(s)
    if min_list[i] != max_list[i]:
        results.append(min_list[i])
        results.append(max_list[i])
results.extend(max_list[i + 1:])
print(results)
# Prints: ['im', 'steve']

然而,如果相同的位置不匹配,那么你有问题该怎么办。我的意思是......那个案子该怎么办?在上面的代码中,我只是将两个条目添加到results列表中,这意味着以下输入:

a = ['hello', 'foo']
b = ['hello', 'world', 'im', 'steve']

会输出:

>>> ['foo', 'world', 'im', 'steve']

(注意列表foo中的a和列表world中的b已添加)

答案 6 :(得分:2)

使用标准for循环检查不在一个或另一个列表中的项目(可能比列表理解更容易理解):

a = ['hello','world', 'foo']
b = ['hello','world','im','steve']
c = a+b
ans = []
for i in c:
    if i not in a or i not in b:
        ans.append(i)
print(ans)

输出:

['foo', 'im', 'steve']

答案 7 :(得分:0)

我建议将^运算符与set(a) ^ set(b)之类的集合一起使用,示例(演示):

>>> a = ['hello','world']
>>> b = ['hello','world','im','steve']
>>> set(a) ^ set(b)
{'steve', 'im'}
>>> sorted(set(a) ^ set(b),key=max([a,b],key=len).index)
['im', 'steve']
>>> 
  

https://docs.python.org/2/library/stdtypes.html#frozenset.symmetric_difference