我有两个列表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也被加上了自己。
这里发生了什么(除了我不了解列表理解的事实)?
答案 0 :(得分:1)
要同时检查条件type(e)==int
和e 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
的每个元素。假设l1
有n
个元素,而l2
有m
个元素。要在列表或数组中查找内容,必须 查看该列表中的每个元素,因此在l2
中查找元素具有O(m)
的复杂性。您正在为l1
的每个元素执行此操作,因此需要n
次。因此,您需要将元素加倍的构建该列表的总复杂度为O(nm)
。
但是,对于集合,每个查找都是O(1)
,因为本质上它是一个哈希表。您仍然必须遍历l1
,因此O(n)
,但是现在查找是固定时间,因此O(1)
。这样一来,我们总共有O(n)
。
如果您应该在列表中包含重复的元素,这会有些棘手,但是您仍然可以使用字典或计数器来摆脱困境。