使用列表理解:对不是字符串或另一个列表的元素的列表元素进行计算

时间:2018-06-22 10:29:24

标签: python list list-comprehension

我有两个列表l1和l2,具有不同类型的元素,如下所示:

l1 = [1,2,3,'4']
l2 = [1,2]

我想对l1中不在l2中且不是string类型的每个元素进行计算。因此,我想知道是否有可能以某种方式隔离列表理解中的整数和字符串。

首先,下面是一个示例,其中如果e不位于l2中,则将l1中的每个元素e添加到自身:

# code
r = [e+e for e in l1 if e not in l2]
print(r)

# result
# [6, '44']

在此重复'4',因为它是字符,所以未添加,但我想忽略该元素。所以我在想我可以隔离类型为(e)== int的元素。

天真的尝试:

# code
r = [e+e for e in l1 if type(e)==int not in l2]

# output
[2, 4, 6]

在这里,l1中的'4'似乎被忽略了,因为它不是整数,但是即使不是l2中的3也被加上了自己。

这里发生了什么(除了我不了解列表理解的事实)?

5 个答案:

答案 0 :(得分:1)

要同时检查条件type(e)==inte not in l2,请使用and运算符

>>> l1 = [1,2,3,'4']
>>> l2 = [1,2]
>>> 
>>> r = [e+e for e in l1 if type(e)==int and e not in l2]
>>> 
>>> r
[6]

答案 1 :(得分:1)

您可以使用isinstance

例如:

l1 = [1,2,3,'4']
l2 = [1,2]

r = [e+e for e in l1 if (e not in l2) and (isinstance(e, int))]
print(r)

输出:

[6]

答案 2 :(得分:1)

某些选项,使用and

r = [e+e for e in l1 if e not in l2 and type(e)==int]

先过滤:

r = [e+e for e in filter(lambda x: type(x)==int, l1) if e not in l2]

全部过滤,与第一个版本相同(但在python2中效率较低):

r = [e+e for e in filter(lambda x: type(x)==int and x not in l2, l1)]

答案 3 :(得分:1)

尝试使用set

l1 = [1,2,3,'4']
l2 = [1,2]
print([e+e for e in [x for x in l1 if not x in set(l1).intersection(l2)] if type(e) == int])

输出:

[6]

答案 4 :(得分:1)

如果这是一个真正的任务,并且您想解决这个问题,我强烈建议您使用集合来摆脱不需要的元素,因为这将使您的时间线性而不是二次。

>>> l1 = [1, 2, 3, '4']
>>> l2 = [1, 2]
>>> s1 = set(l1)
>>> s2 = set(l2)
>>> result = [x * 2 for x in s1.intersection(s2)]
>>> result
[2, 4]

您的原始问题已经在评论和答案中得到了回答。

编辑:如果您对复杂性解释感兴趣:您在代码中所做的工作,则需要在l1中查找l2的每个元素。假设l1n个元素,而l2m个元素。要在列表或数组中查找内容,必须 查看该列表中的每个元素,因此在l2中查找元素具有O(m)的复杂性。您正在为l1的每个元素执行此操作,因此需要n次。因此,您需要将元素加倍的构建该列表的总复杂度为O(nm)

但是,对于集合,每个查找都是O(1),因为本质上它是一个哈希表。您仍然必须遍历l1,因此O(n),但是现在查找是固定时间,因此O(1)。这样一来,我们总共有O(n)

如果您应该在列表中包含重复的元素,这会有些棘手,但是您仍然可以使用字典或计数器来摆脱困境。