2012-03-07 4 views
1

は、Pythonに新しい、私は次の2行は何をすべきかを考え出す時間の一体を抱えているされている:Python - これらの2行は何をしますか?

for i in [j for j in xrange(0, N) if [k for k in xrange(j) if now[k] == now[j]] == []]: 
    for j in [k for k in xrange(1, K + 1) if [l for l in xrange(i) if now[l] == k] == []]: 

は、私のような初心者にはそれを理解できるようにこれを書き換える方法はありますか?ありがとう。

+1

は少しコンテキストを持つことが役立つかもしれない:

#first list comprehension expanded ... first_list = [] for j in xrange(0, N): inner_first_list = [] for k in xrange(j): if now[k] == now[j]: inner_first_list.append(k) if inner_first_list == []: first_list.append(j) #second list comprehension expanded ... second_list = [] for k in xrange(1, K + 1): inner_second_list = [] for l in xrange(i): if now[l] == k: inner_second_list.append(l) if inner_second_list == []: second_list.append(k) #the actual loop ... for i in first_list: for j in second_list: #your loop statement 

あなたがこっちリスト内包のより良い理解を取得します(コードの実行が多少異なる場合があります、コードが唯一の目的を理解するために提示されます)。 「N」と「今」とは何ですか? –

+0

あなたはリスト内包表記を利用しています。 –

+0

2行目の大文字「K」は間違いです。あるいは、コード内の他の場所で定義されているキャプティブ 'K'ですか? – Taymon

答えて

3

私はこのコードはと等価であることはほぼ正だ:(ビット少ない効率的であろうが、うまくコードの背後にある考え方を反映している)

for i in range(0, N): 
    prefix = set(now[:i]) 
    if now[i] in prefix: continue 

    for j in range(1, K + 1): 
    if j in prefix: continue 

    # do something 

か:

for i, j in itertools.product(range(0, N), range(1, K + 1)): 
    prefix = now[:i] 
    if now[i] not in prefix and j not in prefix: 
    # do something with i and j 

しかし、それは混乱した非効率な方法で書かれています(特に[...] == []は厄介で無意味です)。たぶん、単純なものがはるかに適している複雑な構造を使って、かなり巧みに感じる人がいるでしょう。

+0

私はあなたが上にいると思います。 'in'テストがかなり頻繁に実行されるかもしれないのでおそらく' prefix = set(now [:i]) 'を使う価値があります。 –

+0

@gnibbler:そうです。 –

+0

ありがとうございます。それは理にかなっている。このコードを書いた人は誰でも、ここでは複雑な構造(?)を使用していました: p = [私はxrange(0、len(今))のiのためにi [i]!= prev [i]] [0] なぜですか?簡単な方法はありませんか?私はPythonが強力な言語だと知っていますが、このようなことを見ると、BASIC – user1253798

0

あなたが混乱していると思われるのは、入れ子になったlist comprehensionsです。そもそも

、あなたはさらに、ループのために完全に普通でリストを構築するために、ネストされたリストの内包表記を変更して、それをより読みやすくでき変数

firstlist = [j for j in xrange(0, N) if [k for k in xrange(j) if now[k] == now[j]] == []] 
for i in firstlist: 
    secondlist = [k for k in xrange(1, K + 1) if [l for l in xrange(i) if now[l] == k] == []] 
    for j in secondlist: 

にそれらを引き出すことができます。

リストの内容を理解するためには、そのドキュメントのリンクを必ずチェックしてください。彼らは強力な構造物であり、私の意見では、それらを理解している人にとっては読みやすい。しかし、ネストされたリスト内包は、並べ替えるのがむしろ難しいことがあります。

+1

恐ろしいことは、それをさらに難読化して、2つのループを使って、おそらくインナーループが実際に行っていることだけでなく、リストの理解。 – rob05c

4

ええ。読書は肉体的に痛いものでした。これは、でなく、のリスト内包表記を使用する優れた例です。ここで

は、リストの内包表記を使用していない厳格な書き換えです:

for i in xrange(0, N): 
    implicit_list_1 = [] 
    for k in xrange(i): 
     if now[k] == now[i]: 
      implicit_list_1.append(i) 
    if implicit_list_1 == []: 
     for j in xrange(1, K + 1): 
      implicit_list_2 = [] 
      for l in xrange(i): 
       if now[l] == j: 
        implicit_list_2.append(l) 
      if implicit_list_2 == []: 

そしてここでは、より多くの慣用的な書き換えます:

for i in xrange(N): 
    if now[i] not in now[:i]: 
     for j in xrange(1, K + 1): 
      if j not in now[:i]: 

これはA Kは別の変数であると仮定すると、とされていませんミスタイプk

また、これらの1文字の変数名は貧弱なスタイルです。変数の使用を実際に反映する変数名を使用する方がよいでしょう。

0

あなたはおそらくリストの理解と混同されます。リストの理解を書くことさえ難しい。しかし、すでに書かれたリスト理解スクリプトは何を解釈するのが難しいことではない。あなたは親切なコードをほしいと言ったので、以下のコードは新しいユーザーフレンドリーのようなものかもしれません。 Why are Python lambdas useful?