13

今日、BeautifulSoupを使用してzipファイルへのパスのリストを含むディレクトリインデックスを解析していて、興味深いことに気づきました。href取得したタグのすべてのプロパティを取得して、それらを直接キューに入れたいとしましょう。

q = Queue.Queue()
[q.put(tag['href']) for tag in soup.findAll('a')]

理解を何にも割り当てずにインラインで使用して、定期的な呼び出しで別のイテレータを生成できるような状況に遭遇したことはありません。これは悪い習慣と見なされますか?それ自体は「pythonic」ですか?すべてのアイテムをキューに入れるためのより良いワンライナーはありましたか?

4

5 に答える 5

15

これは何度も尋ねられてきました、例えば、ここここ。しかし、それは興味深い質問です。リスト内包表記は、他の目的で使用することを目的としています。

その他のオプションは次のとおりです

  1. 使用map()-基本的にサンプルと同じ
  2. use-filter()関数がNoneを返す場合、空のリストを取得します
  3. 単なるforループ

プレーンループはそれを行うための好ましい方法です。この場合、リスト内包表記、副作用の乱用概念など、他のすべての方法で意味的に正しいです。

Python 3.xではmap()filter()はジェネレーターであるため、それらを反復処理するまで何もしません。したがって、たとえば、が必要にlist(map(...))なります。これにより、さらに悪化します。

于 2013-01-10T01:29:26.207 に答える
8

このスレッドには多くの意見があります。私は自分の組織のコーディング規約からしか話すことができません。

ループに影響を与える方法はたくさんありますが、リスト内包表記の重要な属性は、リストを作成し、反復シーケンスのそれぞれに 1 つのアイテムを使用することです。

>>> import Queue
>>> q = Queue.Queue()
>>> [q.put(item) for item in range(5)]
[None, None, None, None, None]
>>>

この未使用のリストは明らかに無駄です。そのため、この構造は、未使用の戻り値を持つリスト内包表記です。私たちのコードベースに登場することは禁じられています。上記のような明示的なループ、またはそれを消費する何かと組み合わされた生成されたもの、たとえば:

>>> any(q.put(item) for item in xrange(5))
False
>>>

あるいは単に:

>>> for item in xrange(5):
...     q.put(item)
...
>>>

審査に通過する必要があります。

于 2013-01-10T01:50:44.420 に答える
6

これを、soup.findAll によって返されるリストのループと考えると、次のようになります。

for tag in soup.findAll('a'):
    q.put(tag['href'])

これはおそらく、「明示的は暗黙的よりも優れている」ため、より「pythonic」な形式です。

于 2013-01-10T01:25:02.560 に答える
2

おそらくより良いワンライナーではありませんが、(個人的には)次の代わりにこれを行うことを検討します。

for tag in soup.findAll('a'):
    q.put(tag['href'])

悪い習慣になる。まず、ワンライナーは でいっぱいのリストを生成しますが[None]、これはおそらくより非効率的です。第 2 に、コードが何をしているのかすぐにはわかりません。リスト内包表記を見ると、通常、結果のリストが何らかの方法で使用されることを意味します。

于 2013-01-10T01:26:38.180 に答える