如何制作以下代码片段“pythonic”
tag_list = []
for d in docs:
tags = d["tags"]
for tag in tags:
if tag not in tag_list:
tag_list.append(tag)
答案 0 :(得分:10)
在3.x(可能是2.7,我不记得了),你可以做一套理解:
tag_list = {tag for doc in docs for tag in doc["tags"]}
在2.x中,您可以从生成器表达式构建一个集合:
tag_list = set(tag for doc in docs for tag in doc["tags"])
之后,如果您确实需要它作为列表,只需执行list(tag_list)
。
答案 1 :(得分:6)
taglist = set()
for d in docs:
taglist |= set(d["tags"])
taglist = list(taglist)
或
from itertools import chain
taglist = list(set(chain(*(d["tags"] for d in docs))))
或(thx to @ lazy1):
from itertools import chain
taglist = list(set(chain.from_iterable(d["tags"] for d in docs)))
或
import operator
taglist = list(reduce(operator.or_, (set(d["tags"]) for d in docs)))
答案 2 :(得分:2)
help(set.union)
告诉我们
Help on method_descriptor:
union(...)
Return the union of sets as a new set.
(i.e. all elements that are in either set.)
不明确的是你可以传递任意数量的参数,一切都将联合在一起(可能是实现与set.update
共享代码,其中的帮助是指“自身与他人结合” )。什么都没有提到,但确实如此,是参数可以是任何迭代,而不仅仅是其他集合。如果你考虑算法,这是有道理的;实际上没有办法合并两个集合,而不仅仅是迭代一个并将每个元素添加到另一个集合。
因此,我们可以用非常简单和描述性的方式完成工作:
list(set().union(*(d['tags'] for d in docs)))
这比itertools.chain
构造函数(不接受set
)的*args
参数更加明确,这是我的偏好。
(我也非常喜欢嵌套的集合理解方法,虽然嵌套理解的工作方式需要一点时间习惯。)