在列表推导式中使用while循环

20

假设我有一个函数:

x=[]
i=5
while i<=20:
     x.append(i)
     i=i+10
return x

有没有一种方法可以将它转换为像这样的列表理解?

newList = [i=05 while i<=20 i=i+10]

我遇到了语法错误。


1
在您的 while 循环中,i 没有改变,因此它将永远 旋转 - Moses Koledoye
i 从未被修改,因此 i <= 5 总是为真,而 while 循环将永远不会退出。 - tyteen4a03
可能是在列表推导式或生成器表达式中使用while的重复问题。 - KoolAid
1
我已经修复了,在真正的代码中已经增加了,只是在这里忘记添加了。它仍然无法工作。 - cashmoney11
这里的根本问题在于,在while循环中初始化一个整数并手动递增它是Python中迭代数字序列的错误方式。你的第一个代码块更适合写成x = []; for i in range(5, 21, 10): x.append(i),这样更容易转换为推导式。 - TigerhawkT3
3个回答

20

你不需要使用列表推导式来实现这个功能。range 就可以办到:

list(range(5, 21, 10)) # [5, 15]

while循环无法在列表推导式中使用。相反,您可以尝试像这样实现:

def your_while_generator():
    i = 5
    while i <= 20:
        yield i
        i += 10

[i for i in your_while_generator()]

17

不,你不能在列表推导式中使用while

根据Python的语法规范,只允许使用以下原子表达式:

atom: ('(' [yield_expr|testlist_comp] ')' |    '[' [testlist_comp] ']' |    '{' [dictorsetmaker] '}' |    NAME | NUMBER | STRING+ | '...' | 'None' | 'True' | 'False')

列表推导式对应的表达式 - testlist_comp 在 Python 3 中的形式如下:

testlist_comp: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] )

在这里,唯一允许的语句是

test: or_test ['if' or_test 'else' test] | lambdef
star_expr: '*' expr
comp_for: [ASYNC] 'for' exprlist 'in' or_test [comp_iter]

在哪里

comp_if: 'if' test_nocond [comp_iter]
comp_iter: comp_for | comp_if

任何地方都不允许使用单独的while语句。你只能使用for关键字,用于for循环。

解决方法

使用for循环,或利用itertools


3
没有相应的语法可以实现这个,但是你可以使用itertools库。例如:
In [11]: from itertools import accumulate, repeat, takewhile

In [12]: list(takewhile(lambda x: x <= 20, accumulate(repeat(1), lambda x, _: x + 10)))
Out[12]: [1, 11]

(不过这并不符合 Pythonic 的风格,建议使用生成器或显式声明的方式。)

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