【问题标题】:Python get instance from list based on instance variablePython根据实例变量从列表中获取实例
【发布时间】:2011-04-13 20:28:13
【问题描述】:

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

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

但是没有循环有没有更好的方法呢?

感谢您的帮助:)

【问题讨论】:

  • 我想你的意思是 client.screen == search

标签: python list instances


【解决方案1】:

你可以使用filter

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

【讨论】:

  • 如果客户端中的 no 客户端有 screenName == search,这不会引发 IndexError 吗? ...
  • @neurino 我有点假设异常会被处理。但为了完整起见,添加了 try-except 块。
  • 我只需删除 [0] 并返回结果列表。毕竟可能有不止一个匹配,那么如果只需要第一个......
【解决方案2】:

我会使用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!

【讨论】:

  • 非常简洁美观。我假设如果 l 包含具有相同屏幕名称的多个对象,则可以多次调用 next()。
【解决方案3】:

您可以使用generator expression

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)

【讨论】:

    【解决方案4】:

    为此使用字典:

    假设:

    d[screeName] = client
    

    你可以这样做:

    return d[search]  
    

    【讨论】:

      【解决方案5】:

      如果clientsdict,那么您可以使用clients[search]。如果列表中元素的顺序很重要,那么您可以使用来自collectionsOrderedDict

      【讨论】:

        【解决方案6】:

        关于这个话题的最佳讨论是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
        

        【讨论】:

        猜你喜欢
        • 2016-10-02
        • 2010-09-11
        • 2021-03-28
        • 1970-01-01
        • 2014-12-08
        • 2014-08-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多