Python (集合)从多个值中理解

Python (集合)从多个值中理解,python,set-comprehension,Python,Set Comprehension,假设我有一个列表l=[1,2,3],我想创建一组该列表中的所有数字及其平方。理想情况下,在一个单一的理解表达 我能想到的最好办法是(在列表上重复两次): 您自己的代码可以缩短为: set(l).union(x**2 for x in l) 在其中,我将\uu重命名为x,因为\uu表示值不重要,但它很重要 严格地说,您仍然在列表上迭代了两次,但第一次是隐式的 如果您坚持迭代一次,您将得到以下结果: {y for x in l for y in (x, x**2)} 这是一种双重理解,包括以下内

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

我能想到的最好办法是(在列表上重复两次):


您自己的代码可以缩短为:

set(l).union(x**2 for x in l)
在其中,我将
\uu
重命名为
x
,因为
\uu
表示值不重要,但它很重要

严格地说,您仍然在
列表上迭代了两次,但第一次是隐式的

如果您坚持迭代一次,您将得到以下结果:

{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)

依我看,
set(l+[i**2表示l中的i])
是一个更好的解决方案。它比嵌套生成器更清晰

我做了一个基准测试:

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
16.46792753900081
19.72252997099895
它显示
set(l+[i**2表示l中的i])
稍微快一点。我认为这是因为嵌套生成器需要为每个循环创建内部对象
(x,x**2)
,这使得它运行缓慢

更新 输出:

3.0309128219996637
3.1958301850008866
16.46792753900081
19.72252997099895

它比我认为的嵌套生成器更清晰。顺便说一句,它可以简化为
{uu for{uu in l}{124;{u**2 for{uu in l}
@Sraw,它是显式
union()
函数的同义词,仍然需要对列表进行两次迭代。。这很难解释。有一个答案给出了嵌套生成器的理解,我认为这看起来很困惑,尽管它确实很短。但是现在这个答案已经被删除了!当然我写的是一个同义词,我只想说它可以更短更清晰。事实上我找到了一个解决方案:
{*(l+[[u**2代表l中的}}
@Sraw仍然在
l
;-)上迭代两次看看下面的答案。这就是我为@Jens尝试的那种时髦的双重嵌套理解。
s的
顺序总是一个问题。对于这么小的列表,结果毫无意义。当它变大时,首先构建整个列表的事实可能会成为一个因素。更有趣的是有100000多个元素列表的基准测试。@ThijsvanDien更新。