web-dev-qa-db-ja.com

リスト内包表記での「while」ループの使用

私に機能があるとしましょう:

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

このようなリスト内包に変換する方法はありますか?

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

構文エラーが発生します。

8
cashmoney11

リストを理解する必要はありません。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()]
6
Francisco Couzo

いいえ、リスト内包表記では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 を利用します

4
Akshat Mahajan

これには構文はありませんが、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ではありませんが、ジェネレータソリューションまたは明示的なソリューションが推奨されます。)

2
Andy Hayden