Python列表,查找对象名称,效率建议

发布于 2024-09-11 02:46:20 字数 1469 浏览 3 评论 0原文

假设我有以下对象:

class Foo(object):
  def __init__(self, name=None):
    self.name = name

  def __repr__(self):
    return self.name

和一个包含多个实例的列表,例如:

list = [Foo(name='alice'), Foo(name='bob'), Foo(name='charlie')]

如果我想查找具有给定名称的对象,我可以使用以下内容:

def get_by_name(name, list):
  return [foo for foo in list if foo.name == name][-1]

这显然意味着:

print get_by_name('alice', list)
>> alice

但是,是否有更有效的数据结构或检索此类对象的方法?实际上,对象名称仅在运行时已知,并且理论上可以在对象的整个生命周期中发生变化。

有什么建议吗?

更新:

感谢 Matt Joiners 的回答,我已将其更新为支持多个具有相同名称的 Foo

class Foo(object):
    _all_names = {}    
    def __init__(self, name=None):
        self._name = None
        self.name = name        
    @property
    def name(self):
        return self._name        
    @name.setter
    def name(self, name):
        if self._name is not None:
            self._all_names[self._name].remove(self)
        self._name = name
        if name is not None:
            self._all_names.setdefault(name, []).append(self)
    @classmethod
    def get_by_name(cls, name):
        return cls._all_names[name]        
    def __repr__(self):
        return "{0}".format(self.name)

l = [Foo("alice"), Foo("bob"), Foo('alice'), Foo('charlie')]
print Foo.get_by_name("alice")
print Foo.get_by_name("charlie")

对此方法有何评论?

Suppose I have the following object:

class Foo(object):
  def __init__(self, name=None):
    self.name = name

  def __repr__(self):
    return self.name

And a list containing multiple instances, such as:

list = [Foo(name='alice'), Foo(name='bob'), Foo(name='charlie')]

If I want to find an object with a given name, I could use the following:

def get_by_name(name, list):
  return [foo for foo in list if foo.name == name][-1]

Which would obviously mean:

print get_by_name('alice', list)
>> alice

However, is there a more efficient data structure or method for retrieving such objects? In reality, the object names are only known at runtime and could in theory change throughout the lifecycle of the object.

Any advice?

UPDATE:

Thanks to Matt Joiners answer, I have updated it to support multiple Foo's with the same name:

class Foo(object):
    _all_names = {}    
    def __init__(self, name=None):
        self._name = None
        self.name = name        
    @property
    def name(self):
        return self._name        
    @name.setter
    def name(self, name):
        if self._name is not None:
            self._all_names[self._name].remove(self)
        self._name = name
        if name is not None:
            self._all_names.setdefault(name, []).append(self)
    @classmethod
    def get_by_name(cls, name):
        return cls._all_names[name]        
    def __repr__(self):
        return "{0}".format(self.name)

l = [Foo("alice"), Foo("bob"), Foo('alice'), Foo('charlie')]
print Foo.get_by_name("alice")
print Foo.get_by_name("charlie")

Any comments on this approach?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

手心的温暖 2024-09-18 02:46:20

尝试一下大小:

class Foo(object):
    _all_names = {}
    def __init__(self, name=None):
        self.name = name
    @property
    def name(self):
        return self._name
    @name.setter
    def name(self, name):
        self._name = name
        self._all_names[name] = self
    @classmethod
    def get_by_name(cls, name):
        return cls._all_names[name]
    def __str__(self):
        return "Foo({0})".format(self.name)

a = Foo("alice")
b = Foo("bob")
print Foo.get_by_name("alice")

请记住,它保持最小以传达想法,您可以到处进行许多调整和检查。

Try this for size:

class Foo(object):
    _all_names = {}
    def __init__(self, name=None):
        self.name = name
    @property
    def name(self):
        return self._name
    @name.setter
    def name(self, name):
        self._name = name
        self._all_names[name] = self
    @classmethod
    def get_by_name(cls, name):
        return cls._all_names[name]
    def __str__(self):
        return "Foo({0})".format(self.name)

a = Foo("alice")
b = Foo("bob")
print Foo.get_by_name("alice")

Keep in mind it's kept minimal to convey the idea, there are many tweaks and checks you can make here and there.

心如狂蝶 2024-09-18 02:46:20

情况有点混乱。

您将在线性数据结构列表中搜索该对象。寻找某样东西的唯一方法就是一件一件地浏览它。这使得时间随着列表的长度线性增长。所以就是你的速度问题所在。

获得一些速度提升的方法是使用某种哈希方案来使您的对象可以直接通过您感兴趣的键(在您的情况下,name)进行索引。这将允许您以类似于字典键查找的方式查找对象。这是一个恒定时间操作。这基本上就是马特的回答所做的。他将“索引”保留为类级别结构,以便您可以使用散列而不是遍历列表来查找内容。

The situation is a little confusing.

You're going to be searching for this object in a list which is a linear data structure. The only way to look for something is by going through it one by one. This makes the time grow linearly with the length of the list. So that is where your speed issue is.

The way to get some speed gains is to use some kind of hashing scheme to keep your objects directly indexable by the key you're interested in (in your case, name). This will allow you to look up an object in a way similar to dictionary key lookup. It's a constant time operation. This is basically what Matt's answer does. He's keeping an "index" as a class level structure so that you can look things up using hashing rather than by walking a list.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文