在python的List中通过其成员查找对象
Posted
技术标签:
【中文标题】在python的List中通过其成员查找对象【英文标题】:Find object by its member inside a List in python 【发布时间】:2012-06-07 04:25:40 【问题描述】:让我们假设以下简单对象:
class Mock:
def __init__(self, name, age):
self.name = name
self.age = age
然后我有一个列表,其中包含一些像这样的对象:
myList = [Mock("Dan", 34), Mock("Jack", 30), Mock("Oli", 23)...]
是否有一些内置功能可以让我获得所有年龄为 30 岁的 Mocks? 当然我可以遍历他们并比较他们的年龄,但是像
find(myList, age=30)
会很好。有这样的吗?
【问题讨论】:
【参考方案1】:你可以试试filter():
filter(lambda x: x.age == 30, myList)
这将返回一个列表,其中仅包含满足 lambda 表达式的对象。
【讨论】:
如果您打算经常通过此属性进行查找,您可能希望基于该属性维护一个dict
。
至少对于 Python 3.5,你需要list(filter(lambda x: x.age == 30, myList))
来获取列表。
使用 filter()
是旧的经典答案,但列表推导式在 Python 版本之间更快且更便携,如其他答案中所述。【参考方案2】:
列表推导可以选择这些:
new_list = [x for x in myList if x.age == 30]
【讨论】:
也是不错的解决方案,但@dcrooney 答案更适合该功能。有没有人比较什么更快?timeit
在我的机器上为列表理解提供了大约 0.30 微秒,为 lambda 过滤器提供了 0.58 微秒。但它们在这里基本上是等价的,所以你应该使用你喜欢的那个。
这里也对这个问题进行了一些很好的讨论:***.com/a/1247490/317172【参考方案3】:
您可能希望对它们进行预索引 -
from collections import defaultdict
class Mock(object):
age_index = defaultdict(list)
def __init__(self, name, age):
self.name = name
self.age = age
Mock.age_index[age].append(self)
@classmethod
def find_by_age(cls, age):
return Mock.age_index[age]
编辑:一张图片胜过千言万语:
X 轴是 myList 中的 Mocks 数量,Y 轴是运行时间,以秒为单位。
红点是@dcrooney 的 filter() 方法 蓝点是@marshall.ward 的列表理解 隐藏在 X 轴后面的绿点是我的索引 ;-)【讨论】:
非常感谢您的回答。我正要手动重新实现类似的东西。 谢谢。和漂亮的图表。但讨论各种权衡会有所帮助,例如建立索引的额外启动时间,以及它所需的空间。 这是一个很好的解决方案,但您确实会冒以下风险:1. 更高的内存使用率 2. 更多的 CPU 使用率来预计算列表。对于大型列表,这可能会令人望而却步。【参考方案4】:列表推导式几乎总是做这些事情的更快方法(这里是 2 倍),尽管如前所述,如果您关心速度,索引会更快。
~$ python -mtimeit -s"from mock import myList" "filter(lambda x: x.age==21, myList)"
1000000 loops, best of 3: 1.34 usec per loop
~$ python -mtimeit -s"from mock import myList" "[x for x in myList if x.age==21]"
1000000 loops, best of 3: 0.63 usec per loop
对于当前目录下的文件mock.py
:
class Mock:
def __init__(self, name, age):
self.name = name
self.age = age
myList = [Mock('Tom', 20), Mock('Dick', 21), Mock('Harry', 21), Mock('John', 22)]
【讨论】:
以上是关于在python的List中通过其成员查找对象的主要内容,如果未能解决你的问题,请参考以下文章
如何使用python在selenium中通过其id名称的一部分查找元素
如何使用存储库接口在 Spring Data 中通过其嵌套对象的 objectId 查找集合?
如何在sum()语句中通过其位置引用data.table的列