我有两个Python列表:
a = [('when', 3), ('why', 4), ('throw', 9), ('send', 15), ('you', 1)]
b = ['the', 'when', 'send', 'we', 'us']
我需要过滤掉所有与 b 中相似的 a 元素。在这种情况下,我应该得到:
c = [('why', 4), ('throw', 9), ('you', 1)]
什么是最有效的方法?
我有两个Python列表:
a = [('when', 3), ('why', 4), ('throw', 9), ('send', 15), ('you', 1)]
b = ['the', 'when', 'send', 'we', 'us']
c = [('why', 4), ('throw', 9), ('you', 1)]
a = [('when', 3), ('why', 4), ('throw', 9), ('send', 15), ('you', 1)]
b = ['the', 'when', 'send', 'we', 'us']
filtered = [i for i in a if not i[0] in b]
>>>print(filtered)
[('why', 4), ('throw', 9), ('you', 1)]
in
运算符,应将b
转换为set
。这将把查找时间从线性变为常数,当b
是一个长列表时,这将产生巨大的差异。因此,c = set(b)
,然后filtered = [i for i in a if not i[0] in c]
。请注意,最后一行中的b
变成了c
。即使在这个只有5个项目的短列表中,对我来说也会产生25%的速度提升。对于更长的列表(b
中有100个项目),它会产生90%的速度提升。 - Carlc = [item for item in a if item[0] not in b]
或者使用字典推导式:
d = dict(a)
c = {key: value for key in d.iteritems() if key not in b}
{key: value for key, value in d.iteritems() if key not in b}
? - Ericin
很好,但至少在 b
上应该使用集合。如果您有 numpy,当然也可以尝试使用 np.in1d
,但是它是否更快,您应该自行尝试。
# ruthless copy, but use the set...
b = set(b)
filtered = [i for i in a if not i[0] in b]
# with numpy (note if you create the array like this, you must already put
# the maximum string length, here 10), otherwise, just use an object array.
# its slower (likely not worth it), but safe.
a = np.array(a, dtype=[('key', 's10'), ('val', int)])
b = np.asarray(b)
mask = ~np.in1d(a['key'], b)
filtered = a[mask]
difference
等,在这里可能没有用,但通常情况下很有用。in1d
比列表推导式快2倍。 - bmu由于这被标记为numpy
,因此这里提供一个使用numpy.in1d
进行基准测试的numpy解决方案:
In [1]: a = [('when', 3), ('why', 4), ('throw', 9), ('send', 15), ('you', 1)]
In [2]: b = ['the', 'when', 'send', 'we', 'us']
In [3]: a_ar = np.array(a, dtype=[('string','|S5'), ('number',float)])
In [4]: b_ar = np.array(b)
In [5]: %timeit filtered = [i for i in a if not i[0] in b]
1000000 loops, best of 3: 778 ns per loop
In [6]: %timeit filtered = a_ar[-np.in1d(a_ar['string'], b_ar)]
10000 loops, best of 3: 31.4 us per loop
对于5条记录,列表推导式更快。
然而,对于大型数据集,NumPy解决方案比列表推导式快两倍:
In [7]: a = a * 1000
In [8]: a_ar = np.array(a, dtype=[('string','|S5'), ('number',float)])
In [9]: %timeit filtered = [i for i in a if not i[0] in b]
1000 loops, best of 3: 647 us per loop
In [10]: %timeit filtered = a_ar[-np.in1d(a_ar['string'], b_ar)]
1000 loops, best of 3: 302 us per loop
试试这个:
a = [('when', 3), ('why', 4), ('throw', 9), ('send', 15), ('you', 1)]
b = ['the', 'when', 'send', 'we', 'us']
c=[]
for x in a:
if x[0] not in b:
c.append(x)
print c
c
包含不在 b
中的内容。 - Ericin
运算符。 - Arpit简单的方法
a = [('when', 3), ('why', 4), ('throw', 9), ('send', 15), ('you', 1)]
b = ['the', 'when', 'send', 'we', 'us']
c=[] # a list to store the required tuples
#compare the first element of each tuple in with an element in b
for i in a:
if i[0] not in b:
c.append(i)
print(c)
使用过滤器:
c = filter(lambda (x, y): False if x in b else True, a)
X in Y
在 Python 中本身就是一个布尔语句。 - thkangFalse if ... else True
这个表达式过于复杂,难以阅读 - 直接使用 lambda (x, y): x not in b
。此外,在 Python 3 中会导致语法错误- 必须这样写 lambda x: x[0] not in b
因为你使用的参数解包形式已经不再是该语言的一部分了。 - lvcfilter(lambda:...)
本质上很难阅读(相对于筛选推导式而言)。可以推测,您更喜欢使用这种表示法是因为它包含了一个if
条件。 - Eric