[英]Python get instance from list based on instance variable
給定一個實例列表,比如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'
這是相當短的和恕我直言的優雅,但可能效率較低,因為列表理解將迭代所有列表。 如果您確實想避免這種開銷,可以使用括號而不是方括號來獲取生成器而不是新列表:
>>> g = (e for e in l if e.screenName == 'b')
>>> g
<generator object <genexpr> at 0x2e5440>
>>> g.next()
<__main__.Client instance at 0x2e52b0>
但請注意, next()
方法只能調用一次。
HTH!
你可以使用生成器表達式 ,
client=next(client for client in clients if client.screenName == search)
但不是說你仍然以不同的方式循環。
注意:如果沒有客戶端滿足條件client.screenName == search
則上面將引發StopIteration
異常。 這與你的for-loop
不同,它不會返回任何東西而退出循環。
根據您的情況,提出異常可能比靜默失敗更好。
如果您不想使用默認值而不是StopIteration
異常,則可以使用next
參數的2參數:
client=next(client for client in clients if client.screenName == search,
default_value)
使用字典:
假設:
d[screeName] = client
你可以這樣做:
return d[search]
如果clients
是一個dict
那么你可以使用clients[search]
。 如果列表中元素的順序很重要,那么您可以使用collections
的OrderedDict
。
有關此主題的最佳討論,請參見此鏈接
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.