Python中一行代码实现的'for'循环

16
当我尝试像下面这样在一行中使用for语句时,
def get_cubes(x):
ls=[]
ls.append(pow(item*3, 3)) for item in range(int((x-x%3)/3)+1)
return ls

总是会出现错误:

File "<ipython-input-47-8c391c3d568a>", line 3
ls.append(pow(item*3, 3))  for item in range(int((x-x%3)/3)+1)
                             ^
SyntaxError: invalid syntax

但是当我使用常规的循环方法for时,它却可以正常工作。为什么?


2
因为你使用有效的Python语法编写了常规的for循环。 - Stop harming Monica
3
这回答是否能解决你的问题?[Python单行“for”表达式] - ahmedg
3个回答

25

解决方案

如果您严格要求只有一行代码,那么这就是解决方案:

get_cubes = lambda x: [pow(i, 3) for i in range(0, x+1, 3)]

但是,既然在Python中清晰度和可读性始终应该是优先考虑的,最好像@daniel一样将其编写为函数:

def get_cubes(x):
    return [pow(i, 3) for i in range(0, x+1, 3)]

输出

使用for循环测试该函数,您会得到以下结果:

for i in range(20):
    print(i, ':', get_cubes(i))

0 : [0]
1 : [0]
2 : [0]
3 : [0, 27]
4 : [0, 27]
5 : [0, 27]
6 : [0, 27, 216]
7 : [0, 27, 216]
8 : [0, 27, 216]
9 : [0, 27, 216, 729]
10 : [0, 27, 216, 729]
11 : [0, 27, 216, 729]
12 : [0, 27, 216, 729, 1728]
13 : [0, 27, 216, 729, 1728]
14 : [0, 27, 216, 729, 1728]
15 : [0, 27, 216, 729, 1728, 3375]
16 : [0, 27, 216, 729, 1728, 3375]
17 : [0, 27, 216, 729, 1728, 3375]
18 : [0, 27, 216, 729, 1728, 3375, 5832]
19 : [0, 27, 216, 729, 1728, 3375, 5832]

解释

对于那些问为什么@daniel的代码起作用的人:

原始代码执行以下操作:

  1. 给定一个x,从0迭代到3除x的个数加上1
  2. 对于每个x,将其乘以3并将其立方
  3. 返回包含步骤2结果的列表

第一步最初编写为

range(int((x - x%3) / 3) + 1)

将一个数除以 3 的余数减去后再除以 3,最后加上 1。但是同样的结果可以通过获取 x 除以 3 的整数部分,然后加上 1 来实现,具体如下:

int(x / 3) + 1

第二步是将每个迭代乘以3,然后将其提高到3次方,但是这种"乘法"也可以使用范围(就像@daniel所做的那样)来实现:

range(0, x+1, 3)

迭代从0x+1,步长为3,并产生相同的结果。即x10

range(0, 10 + 1, 3)  |    i*3 for i in range(int(x / 3) + 1)
============================================================
0                    |    0*3 = 0
3                    |    1*3 = 3
6                    |    2*3 = 6
9                    |    3*3 = 9

对于步骤3,我们只需要应用pow(x, 3)(或x ** 3),然后使用列表推导式将所有内容放在一行中,然后我们可以将其适应于lambda函数或函数的return语句中。

[pow(i, 3) for i in range(0, x+1, 3)]

7
for循环的正确语法是:
def get_cubes(x):
    ls = []
    for item in range(int((x-x%3)/3)+1):
        ls.append(pow(item*3, 3)) 
    return ls

也许您正在寻找列表推导式,这是一种生成列表的方法,当循环体仅添加到列表中时使用它:
def get_cubes(x):
    ls = [(item*3) ** 3 for item in range(int((x-x%3)/3)+1)]
    return ls

或者简单来说:
def get_cubes(x):
    return [i ** 3 for i in range(0, x+1, 3)]

2
如果您能向OP解释一下您的代码是如何替换错误代码的,那就太好了。很明显,他/她似乎是个初学者。 - Sheldore

5

我的答案采用了你的方法(代码),但是做了一些改进。与你的代码进行比较,你会找出错误在哪里。我添加了注释#来解释这些变化。

def get_cubes(x):
    ls=[] # create an empty list outside the for loop once
    for item in range(int((x-x%3)/3)+1): # for loop for iterating through elements
        ls.append(pow(item*3, 3)) # append one item at a time
    return ls

print (get_cubes(10))                                   
> [0, 27, 216, 729]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接