58

夢を見ていたかどうかは覚えていませんが、次のような機能があったことを思い出しているようです。

foo in iter_attr(array of python objects, attribute name)

私はドキュメントを調べましたが、この種のものは明白なリストされたヘッダーに該当しません

4

8 に答える 8

47

リスト内包表記を使用すると、一時的なリストが作成され、検索されるシーケンスが大きい場合、すべてのメモリが消費される可能性があります。シーケンスが大きくなくても、リストを作成するということはin、検索を開始する前にシーケンス全体を反復することを意味します。

一時リストは、ジェネレータ式を使用して回避できます。

foo = 12
foo in (obj.id for obj in bar)

これで、が無限に長くても、obj.id == 12の開始近くにある限りbar、検索は高速になります。bar

@Matt が示唆したhasattrように、オブジェクトのいずれかに属性barが欠落している可能性がある場合に使用することをお勧めします。id

foo = 12
foo in (obj.id for obj in bar if hasattr(obj, 'id'))
于 2008-09-11T22:42:14.047 に答える
12

特定の属性を持つオブジェクトのリストを取得しようとしていますか?もしそうなら、リスト内包はこれを行う正しい方法です。

result = [obj for obj in listOfObjs if hasattr(obj, 'attributeName')]
于 2008-08-03T15:59:19.797 に答える
10

あなたはいつでも自分で書くことができます:

def iterattr(iterator, attributename):
    for obj in iterator:
        yield getattr(obj, attributename)

タプル、リストなど、反復するものなら何でも動作します。

私は python が大好きです。これにより、このようなものは非常にシンプルになり、必要以上に面倒なことはなくなります。このようなものを使用すると、非常にエレガントになります。

于 2008-08-27T20:13:49.943 に答える
7

いいえ、あなたは夢を見ていませんでした。Pythonには、リストを非常にエレガントに操作できる非常に優れたリスト内包システムがあります。達成したい内容に応じて、これはいくつかの方法で実行できます。本質的に、あなたがしていることは「criteria.matchesの場合、リスト内のアイテムについて」と言っていることであり、そこから結果を反復処理するか、結果を新しいリストにダンプすることができます。

ここでは、 Dive Into Pythonの例を紹介します。これは、非常にエレガントで、私よりも賢いからです。ここでは、ディレクトリ内のファイルのリストを取得し、正規表現の基準に一致するすべてのファイルのリストをフィルタリングしています。

    files = os.listdir(path)                               
    test = re.compile("test\.py$", re.IGNORECASE)          
    files = [f for f in files if test.search(f)]

たとえば、正規表現を使用せずにこれを行うことができます。たとえば、最後の式が一致に対してtrueを返す場合などです。filter()関数を使用するなどの他のオプションもありますが、選択する場合は、これを使用します。

エリック・シップル

于 2008-08-03T14:30:50.850 に答える
6

あなたが考えている機能はおそらくoperator.attrgettter. たとえば、各オブジェクトの「id」属性の値を含むリストを取得するには:

import operator
ids = map(operator.attrgetter("id"), bar)

リストに id == 12 のオブジェクトが含まれているかどうかを確認したい場合、すっきりと効率的な (つまり、リスト全体を不必要に反復しない) 方法は次のとおりです。

any(obj.id == 12 for obj in bar)

リストの遅延反復を保持しながら、attrgetter で 'in' を使用する場合:

import operator,itertools
foo = 12
foo in itertools.imap(operator.attrgetter("id"), bar)

于 2011-02-05T08:10:41.457 に答える
5

私が考えていたのはリスト内包表記で実現できるのですが、少しすっきりした機能があると思いました。

つまり、「bar」はオブジェクトのリストであり、そのすべてに属性「id」があります。

神話上の機能的な方法:

foo = 12
foo in iter_attr(bar, 'id')

リスト内包法:

foo = 12
foo in [obj.id for obj in bar]

振り返ってみると、リスト内包法はとにかくかなりきちんとしています。

于 2008-08-03T16:13:29.363 に答える
3

リモートでまともなサイズのものを検索する場合は、辞書またはセットを使用するのが最善の策です。それ以外の場合は、基本的に、目的の要素に到達するまで、イテレーターのすべての要素を反復処理する必要があります。

これが必ずしもパフォーマンスに敏感なコードではない場合は、リスト内包法が機能するはずです。ただし、イテレータのすべての要素を調べてから、必要なものが見つかるまでもう一度戻るため、かなり非効率的であることに注意してください。

Pythonには、最も効率的なハッシュアルゴリズムの1つがあることを忘れないでください。あなたの利点にそれを使用してください。

于 2008-08-27T20:30:22.070 に答える
0

おもう:

#!/bin/python
bar in dict(Foo)

あなたが考えていることです。Python(Pythonのバージョンのハッシュテーブル)のディクショナリ内に特定のキーが存在するかどうかを確認する場合、2つの方法で確認できます。1has_key()つ目は辞書に添付されているメソッドで、2つ目は上記の例です。ブール値を返します。

それはあなたの質問に答えるはずです。

そして今、これを以前に与えられたリスト内包の答えに結び付けるための少し外れたトピックです(もう少し明確にするために)。 リスト内包表記は、修飾子を使用して基本的なforループからリストを作成します。例として(少し明確にするために)、リスト内包in dict表記で言語構造を使用する方法:

2foo次元の辞書があり、キーを含む2次元の辞書のみが必要だとしますbar。これを行うための比較的簡単な方法は、次のように条件付きのリスト内包表記を使用することです。

#!/bin/python
baz = dict([(key, value) for key, value in foo if bar in value])

ステートメントの最後にあることに注意してください**。これは、条件を満たすキーと値のペアのみを保持するようにリスト内包if bar in value表記に指示する変更句です。**この場合、fooの辞書のみを含む新しい辞書です。これにはバーが含まれています(このコード例で何も見逃していないことを願っています... docs.python.orgチュートリアルsecnetix.deにあるリスト内包表記のドキュメントを参照する必要があるかもしれません。将来質問があります。)baz

于 2008-08-03T15:47:22.100 に答える