让我们假设以下简单的对象:
class Mock:
def __init__(self, name, age):
self.name = name
self.age = age
然后我有一个包含这样的对象的列表:
myList = [Mock("Dan", 34), Mock("Jack", 30), Mock("Oli", 23)...]
是否有一些内置功能,我可以获得年龄为30岁的所有模拟? 当然,我可以在他们身上迭代并比较他们的年龄,但是像
find(myList, age=30)
会很好。有类似的东西吗?
答案 0 :(得分:35)
您可能希望对它们进行预索引 -
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轴是以秒为单位的运行时间。
答案 1 :(得分:34)
答案 2 :(得分:19)
列表理解可以选择这些:
new_list = [x for x in myList if x.age == 30]
答案 3 :(得分:5)
列表推导几乎总是以更快的方式完成这些事情(这里速度提高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)]