给定一个实例列表,比如clients
我试图根据单个实例变量screenName
的值从列表中提取项目。我知道我可以这样做:
for client in clients:
if client.screenName = search:
return client
但如果没有循环,有没有更好的方法呢?
感谢您的帮助:)
答案 0 :(得分:6)
您可以使用filter
try:
filter(lambda client: client.screenName == search, clients)[0]
except IndexError:
# handle error. May be use a default value
答案 1 :(得分:1)
我会使用list comprehensions。假设这是你的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!
答案 2 :(得分:1)
您可以使用generator expression,
client=next(client for client in clients if client.screenName == search)
但不是你仍然以不同的方式循环。
注意:如果没有客户满足条件client.screenName == search
,则上述内容将引发StopIteration
异常。这与您的for-loop
不同,StopIteration
不会返回任何内容而退出循环。
根据您的情况,提出异常可能比默默失败更好。
如果您不想使用默认值而不是next
例外,则可以使用client=next(client for client in clients if client.screenName == search,
default_value)
的2参数版本:
{{1}}
答案 3 :(得分:0)
使用字典:
假设:
d[screeName] = client
你可以这样做:
return d[search]
答案 4 :(得分:0)
如果clients
是dict
,那么您可以使用clients[search]
。如果列表中元素的顺序很重要,那么您可以使用OrderedDict
中的collections
。
答案 5 :(得分:0)
有关此主题的最佳讨论,请参阅此link
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