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

时间:2011-04-13 20:28:13

标签: python list instances

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

for client in clients:
  if client.screenName = search:
    return client

但如果没有循环,有没有更好的方法呢?

感谢您的帮助:)

6 个答案:

答案 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)

如果clientsdict,那么您可以使用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