2010-11-19 14 views
7

これはリスト内包表記なしで1行で記述できますか?for-ifリスト内包表記が1行にない

for x in vec: 
    if x > 3: 
     ... 
     ... 
+10

なぜですか? /なぜ1行ですか? – kennytm

+0

私はそれにあまり慣れていませんが、ここで 'lambda'ステートメントが適切でしょうか? – Blender

+0

@blender: 'ラムダ 'だけではナンセンスはありません。 'i-/filter'の述語として、はい。 – delnan

答えて

3

いいえ、あなたはできません。 Python language reference状態:

複合文は、1つまたはそれ以上の から成る句は ヘッダとから構成され、特定の化合物 文の句 ヘッダが同じであるすべての「節」「スイート」。 インデントレベル。各句ヘッダ は、一意に識別する キーワードで始まり、コロンで終わります。スイート は、 a節によって制御される文のグループです。スイートは、ヘッダーと同じ行にある セミコロンで区切られた簡単なステートメント 、ヘッダーのコロンに続いて 、または は後続の行で1つ以上のインデント付きステートメントにすることができます。 後者の 形式のスイートには、入れ子になった 複合ステートメントを含めることができます。それがこれにif節以下 else節が属します明らか ではありません主な理由は以下のは、違法 です:

if test1: if test2: print x 

は確かに、Pythonは上記のネストされたIFSのため SyntaxErrorを生成します。 forがインデントなしの文が続いているとき、その文だけ simple_stmtインスタンスを許可 stmt_list、でなければならないことを

for_stmt ::= "for" target_list "in" expression_list ":" suite 
       ["else" ":" suite] 

suite   ::= stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT 

stmt_list  ::= simple_stmt (";" simple_stmt)* [";"] 

注:より正式forについては、これは、Pythonでの文法です。 simple_stmtはこれです:iffor様化合物のステートメントが含まれていません

simple_stmt ::= expression_stmt 
       | assert_stmt 
       | assignment_stmt 
       | augmented_assignment_stmt 
       | pass_stmt 
       | del_stmt 
       | print_stmt 
       | return_stmt 
       | yield_stmt 
       | raise_stmt 
       | break_stmt 
       | continue_stmt 
       | import_stmt 
       | global_stmt 
       | exec_stmt 


つまり、Pythonの構文は明快さを目指しています。したがって、このようなステートメントをネストしないほうがいいです。これはジェネレーター/リストの理解が行われたものです。あなたの計算が1行分のシンプルなものであると考えるなら、あなたのための理解があります。それ以外の場合は、すべての行を1行にまとめることでコードを混乱させたくありません。字下げでうまく分割してください。いくつかの余分な回線は、最近多くの費用がかかりません。

+1

私は彼が1つの行に2つのステートメントを置くことができるかどうか尋ねていたとは思わない。私は彼が、これらの2つのステートメントの全体的な効果を1行に出すことを望んでいると思います。 – Gerrat

+0

@Eli:彼はこの例に2行の省略記号をつけているので、 'x'で手続き的に何かをやって、リストの理解を容認できない解決策にしています。 **リスト内包はループを単一のoneliner **にする方法ではありません**。 – delnan

+0

@delnan:そうかもしれない、私は本当に知らない。 OP-intention-interpretationは楽しいSOのゲームではありませんか? :-)私はロベルトが彼が本当に望んでいることを明確にすることを奨励します。 –

-1

あなたはこのように代を想像することができます:

def do_something(value): 
    ... 

def do_otherthing(value): 
    ... 


for x in t: do_something(x) if x>3 else do_otherthing(x) 
+0

それはまさに彼が求めていなかったものです: "リストの理解なし" –

+1

もう一度質問をお読みください。 –

+0

質問はこれを特に質問しません - '...'がいくつかのステートメントであるため、リストの理解は非慣用的なものになります。 – delnan

0

それはできますが、リスト内包表記/ジェネレータ式は、ここで使用されるべきであることを正確にソートされています。 ifブロックで何をしたいかに応じて、mapまたはreduceという形式を使用できますが、リストの補完とジェネレータの式はおそらく最も良い方法です。

+0

私はifの後に複数の行を書く必要があるので、飛ぶつもりはありません。 – Roberto

+0

@Robertoあなたが必要とするものを実行し、それをリスト内包の中で使用する関数を書く –

+0

そのようなことをするたびにfor/ifの行を追加しますが、関数を宣言するために1行追加します:) – Roberto

0

はい

フィルタにおけるxの

(ラムダI:> 3、VEC):

+0

Python 2では、値を遅延的に生成するのではなく、即座に新しいリストを作成します。 – delnan

+0

http://docs.python.org/library/itertools.html#itertools.ifilter –

3

参照@KennyTM ...それだけ圧縮する理由はありません。

言われて何

for x in (i in vec if i > 3)は仕事だけでなく、itertools.ifilterを行います(または単に組み込みfilter Pythonの3中)lambda x: x > 3述語を持ちます。これらはすべてのイテラブルでも動作し、怠け者です(ループ中にbreakを指定した場合は、1つのアイテムをあまりにも多くチェックしませんでした)。

+0

コメントに記載されているOPのように、「* x *が大文字の場合は、入力する必要があります(毛髪を引っ張る瞬間)、おそらく 'フィルター' + 'ラムダ 'がこの質問に対する適切な答えです。 – tzot

関連する問題