インスタンスのリストが与えられたclients
として、単一のインスタンス変数の値に基づいてリストからアイテムを抜き取ろうとしているとしますscreenName
。私はこれを行うことができることを知っています:
for client in clients:
if client.screenName = search:
return client
しかし、ループなしでこれを行うより良い方法はありますか?
ご協力いただきありがとうございます :)
使用できますfilter
try:
filter(lambda client: client.screenName == search, clients)[0]
except IndexError:
# handle error. May be use a default value
リスト内包表記を使用します。これがあなたのClient
クラスだとします:
>>> class Client:
... def __init__(self, screenName):
... self.screenName = screenName
このクライアントのリストを取得した場合:
>>> l = [Client('a'), Client('b'), Client('c')]
...指定された名前のクライアントのみを含むリストを取得できます。
>>> [e for e in l if e.screenName == 'b']
[<__main__.Client instance at 0x2e52b0>]
ここで、最初の (おそらく唯一の) 要素を取得します。
>>> [e for e in l if e.screenName == 'b'][0]
<__main__.Client instance at 0x2e52b0>
>>> c = [e for e in l if e.screenName == 'b'][0]
>>> c.screenName
'b'
これは非常に短く、IMHOエレガントですが、リスト内包表記がすべてのリストを反復処理するため、効率が低下する可能性があります。このオーバーヘッドを避けたい場合は、角括弧の代わりに括弧を使用して、新しいリストの代わりにジェネレーターを取得できます。
>>> g = (e for e in l if e.screenName == 'b')
>>> g
<generator object <genexpr> at 0x2e5440>
>>> g.next()
<__main__.Client instance at 0x2e52b0>
ただし、このnext()
メソッドは 1 回しか呼び出せないことに注意してください。
チッ!
ジェネレーター式を使用できます。
client=next(client for client in clients if client.screenName == search)
しかし、別の方法で、まだループしているわけではありません。
注: 条件を満たすクライアントがない場合client.screenName == search
、上記はStopIteration
例外を発生させます。for-loop
これは、何も返さずにループから抜け出す とは異なります。
状況によっては、黙って失敗するよりも例外を発生させる方がよい場合があります。
例外の代わりにデフォルト値が必要ない場合はStopIteration
、次の 2 パラメータ バージョンを使用できますnext
。
client=next(client for client in clients if client.screenName == search,
default_value)
の場合clients
は、dict
そのまま使用できますclients[search]
。リスト内の要素の順序が重要な場合は、OrderedDict
fromを使用できますcollections
。
このトピックに関する最良の議論は、このリンクにあります
return find(lambda client: client.screenName == search, clients)
これには、次のようにすべてのタイプのリストで機能する一般的な検索関数を定義する必要があります。
def find(f, seq):
"""Return first item in sequence where f(item) == True."""
for item in seq:
if f(item):
return item
これには辞書を使用します。
これを仮定:
d[screeName] = client
これを行うことができます:
return d[search]