1 行 'pythonic' 代码 returns 一个集合而不是一个列表

1 liner 'pythonic' code that returns a set rather than a list

我想做下面的代码,除了在一个整洁的 1-liner 中:

terms_set = set([])
for term in terms: 
    if index.has_key(term): 
        terms_set.add(index[term])

可以吗?必须return一套。

terms_set = set([index[term] for term in terms if index.has_key(term)])

这个?

set(index[t] for t in terms if t in index)

请注意 has_key 已弃用,请改用 key in dict

terms_set = set(index[term] for term in terms if index.has_key(term))

您可以使用集合理解:

terms_set = {index[term] for term in terms if term in index}

请注意 key in dict 优于 dict.has_key,后者 was deprecated in Python 2 并且在 Python 中不可用 3.

所以看起来你希望 term_set 包含 index(一些字典)中的所有值,只要它的键是 alsoterms 中提到(有些可迭代)。将两者视为集合,这就是交集,粗略地说,至少对于键,set(terms) & set(index),但这会生成两个集合,我们实际上对两者都不感兴趣(我们想要值,而不是键)。我们可以用 set(terms).intersection(index) 省略其中一个(反之亦然,取决于哪个较大(我们希望左侧较小)。

我们可以使用我们的好朋友map来获取值。

这个怎么样?

term_set = map(index.get, set(terms).intersection(index))

甚至:

term_set = map(index.get, index.keys() & terms)

(在python2.7中,你需要index.viewkeys())

嗯...考虑一下,dict.get 可以 return 一个默认值(即 None),我们可以在事后删除它(如果它发生了)

term_set = set(map(index.get, terms))
term_set.discard(None)

构造NO个中间集合(假设python3,否则map应该是itertools.imap

尽管如果 None 可以作为索引中的值出现,您最终不得不做一些乏味的事情,例如:

sentinel = object()
term_set = {index.get(term, sentinel) for term in terms} - {sentinel}

一点也不比公认的答案好。