Python基于实例变量从列表中获取实例

Python基于实例变量从列表中获取实例,python,list,instances,Python,List,Instances,给定一个实例列表,比如说clients,我试图根据单个实例变量screenName的值从列表中提取一个项目。我知道我能做到: for client in clients: if client.screenName = search: return client 但是,有没有更好的方法来实现这一点而不使用循环 感谢您的帮助:)为此使用词典: 假设: d[screeName] = client 您可以这样做: return d[search] 如果clients是一个dict,

给定一个实例列表,比如说
clients
,我试图根据单个实例变量
screenName
的值从列表中提取一个项目。我知道我能做到:

for client in clients:
  if client.screenName = search:
    return client
但是,有没有更好的方法来实现这一点而不使用循环


感谢您的帮助:)

为此使用词典:

假设:

d[screeName] = client
您可以这样做:

return d[search]  

如果
clients
是一个
dict
,那么您可以使用
clients[search]
。如果列表中元素的顺序很重要,则可以使用我将使用的
集合中的
orderedict
。假设这是您的
客户机
类:

>>> 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代表e,如果e.screenName=='b']
[]
现在,只需获取第一个元素(也被认为是唯一的元素):

>>> [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'
>[e代表l中的e,如果e.screenName=='b'][0]
>>>c=[e代表e,如果e.screenName=='b'][0]
>>>c.屏幕名称
“b”
这是非常简短和优雅的,但效率可能会更低,因为列表理解将迭代所有列表。如果您确实希望避免这种开销,可以使用括号而不是方括号获取生成器而不是新列表:

>>> g = (e for e in l if e.screenName == 'b')
>>> g
<generator object <genexpr> at 0x2e5440>
>>> g.next()
<__main__.Client instance at 0x2e52b0>
>>g=(如果e.screenName=='b',则e代表l中的e)
>>>g
>>>g.下一步()
但是,请注意,
next()
方法只能调用一次


您可以使用
过滤器

try:
    filter(lambda client: client.screenName == search, clients)[0]
except IndexError:
    # handle error. May be use a default value
你可以用一个

但并不是说你还在循环,只是以不同的方式

注意:如果没有客户端满足条件
client.screenName==search
,则上述操作将引发
StopIteration
异常。这与循环
不同,循环不返回任何内容而退出循环

根据您的情况,引发异常可能比默默失败要好

如果不希望使用默认值而不是
StopIteration
异常,则可以使用
next
的双参数版本:

client=next(client for client in clients if client.screenName == search, 
            default_value)

关于这个话题最好的讨论就是这个

这要求您定义一个通用查找函数,该函数适用于所有类型的列表,如下所示:

def find(f, seq):
  """Return first item in sequence where f(item) == True."""
  for item in seq:
    if f(item): 
      return item

我想你指的是client.screen==search我想你指的是
s/find/filter/
?不,我指的是我写的,不要投反对票。请参见此处:如果客户端中没有客户端具有
screenName==search
,这是否会引发
索引器
@neurino我有点假设异常会得到处理。但是为了完整起见,添加了
try except
块。我只需删除
[0]
并返回结果列表。毕竟可能会有不止一场比赛,如果只需要第一场的话……非常简洁和漂亮。如果l包含多个具有相同屏幕名的对象,我假设可以多次调用next()。
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