制作这个pythonic

时间:2012-05-29 23:32:51

标签: python

如何制作以下代码片段“pythonic”

 tag_list = []
 for d in docs:
        tags = d["tags"]
        for tag in tags:
            if tag not in tag_list:
                tag_list.append(tag)

3 个答案:

答案 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参数更加明确,这是我的偏好。

(我也非常喜欢嵌套的集合理解方法,虽然嵌套理解的工作方式需要一点时间习惯。)