(设置)从多个值理解

时间:2017-12-14 01:43:39

标签: python set-comprehension

假设我有一个列表l = [1,2,3],我想在该列表及其正方形中创建一组所有数字。理想情况下,在单一的理解表达中。

我能想到的最好的是(列表上的两次迭代):

set(_ for _ in l).union(_ * _ for _ in l)

2 个答案:

答案 0 :(得分:0)

您自己的代码可缩短为:

set(l).union(x**2 for x in l)

我将_重命名为x,因为_表示该值并不重要,但确实如此。

严格来说,你仍在两次list上进行迭代,但第一次是隐含的。

如果你坚持迭代一次,你会得到这个:

{y for x in l for y in (x, x**2)}

这是一种双重理解,包含以下内容:

result = set()
for x in l:
    for y in (x, x**2):
        result.add(y)

答案 1 :(得分:0)

IMO,set(l + [i ** 2 for i in l])是一个更好的解决方案。它比嵌套的生成器理解更清晰。

我做了一个基准测试:

import timeit
l = list(range(5))
print(timeit.timeit("set(l + [_ ** 2 for _ in l])", 'from __main__ import ' + ', '.join(globals())))
print(timeit.timeit("{y for x in l for y in (x, x**2)}", 'from __main__ import ' + ', '.join(globals())))

输出:

3.0309128219996637
3.1958301850008866

它显示set(l + [i ** 2 for i in l])更快一点。我认为原因是嵌套的生成器理解需要为每个循环创建内部对象(x, x**2),这使得它变慢。

更新

import timeit
l = list(range(200000))
print(timeit.timeit("set(l + [_ ** 2 for _ in l])", 'from __main__ import ' + ', '.join(globals()), number=100))
print(timeit.timeit("{y for x in l for y in (x, x**2)}", 'from __main__ import ' + ', '.join(globals()), number=100))

输出:

16.46792753900081
19.72252997099895