Raf*_*l T 20 python search list find
让我们假设以下简单的对象:
class Mock:
def __init__(self, name, age):
self.name = name
self.age = age
Run Code Online (Sandbox Code Playgroud)
然后我有一个包含这样的对象的列表:
myList = [Mock("Dan", 34), Mock("Jack", 30), Mock("Oli", 23)...]
Run Code Online (Sandbox Code Playgroud)
是否有一些内置功能,我可以获得年龄为30岁的所有模拟?当然,我可以对自己进行迭代并比较它们的年龄,但类似于
find(myList, age=30)
Run Code Online (Sandbox Code Playgroud)
会好的.有类似的东西吗?
dck*_*ney 35
你可以试试filter():
filter(lambda x: x.age == 30, myList)
Run Code Online (Sandbox Code Playgroud)
这将返回一个列表,其中只包含那些满足lambda表达式的对象.
Hug*_*ell 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]
Run Code Online (Sandbox Code Playgroud)
编辑:一张图片胜过千言万语:

X轴是myList中的Mocks数,Y轴是运行时的秒数.
mar*_*ard 19
列表推导可以选择这些:
new_list = [x for x in myList if x.age == 30]
Run Code Online (Sandbox Code Playgroud)
列表推导几乎总是以更快的方式完成这些事情(这里速度提高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
Run Code Online (Sandbox Code Playgroud)
对于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)]
Run Code Online (Sandbox Code Playgroud)