2011-12-06 85 views
0

想象一下,有随机的单词列表:从列表中删除所有但某些词(如白名单)

words = ['elephant', 'dog', 'blue', 'sam', 'white', 'red', 'sun', 'moon'] 

而且我要删除所有,但下面的话(如白名单):

colors = ['red', 'green', 'blue', 'orange', 'white'] 

我想产生下面的列表(顺序事项):

filtered = ['blue', 'white', 'red'] 

我想过这样的事情(W这工作很好):

filtered = filter (lambda a: a == 'red' or a == 'green' or a == 'blue' or a == 'orange' or a == 'white', words) 

但这是真的最好/最有效的方式?

回答

4

如果你想维持秩序,有效地过滤掉非颜色,创建颜色set,使in检查速度更快,那么你可以去通所有单词并过滤掉非颜色

words = ['elephant', 'dog', 'blue', 'sam', 'white', 'red', 'sun', 'moon'] 
colors = set(['red', 'green', 'blue', 'orange', 'white']) 
print [word for word in words if word in colors] 

输出:

['blue', 'white', 'red'] 
1
filtered = filter(lambda a: a in whitelis, words) 

应该做的伎俩

这也可以写成一个列表理解

filtered = [x for x in letters if x in whitelist] 

如下所述,您可以使用集类型,以确保在白名单中的每一个字是独特的。当你的白名单没有被硬编码时,这很有用,但是不知何故,例如从数据库中的记录中生成。

1

使用设置操作:

words = ['elephant', 'dog', 'blue', 'sam', 'white', 'red', 'sun', 'moon'] 
colors = ['red', 'green', 'blue', 'orange', 'white'] 
filtered = set(words).difference(colors) 
+0

这种方法使得两个关键假设:1),要么在'words'名单没有按不包含重复项,或者不需要保留,2)“过滤”顺序无关紧要。 –

+0

这是一个有效的观察 –

2
words = ['elephant', 'dog', 'blue', 'sam', 'white', 'red', 'sun', 'moon'] 
filterset = frozenset(['red', 'green', 'blue', 'orange', 'white']) 
filtered = [x for x in words if x in filterset] 

该解决方案的优点是即使对于相对较大的filterset它也会相对较快,并且它不会假定words列表仅包含唯一条目。

您可以将filterset作为filterlist,但这会损害性能,尤其是在列表很大的情况下。

1

虽然列表理解通常被认为是更Python,我喜欢的功能filter,如果我们可以把它写不lambda

>> filter(set(colors).__contains__, words) 
['blue', 'white', 'red'] 
相关问题