Python 如何使用对象属性列表对对象列表进行排序

Python 如何使用对象属性列表对对象列表进行排序,python,Python,我有一个id为(object.id)的对象列表和一个id列表。使用ID列表对对象列表排序最有效的方法是什么?我有以下解决方案。。。只是想知道有没有更快的 输入: result=具有用户id(user.id)的用户对象列表 ID列表=用户ID列表,例如[3,2,5,8,9] 输出: 根据ID列表排序的用户对象列表 代码: 您可以首先将用户放入dict中: usrdict = {} for user in result: usrdict[user.id] = user 然后,根据用

我有一个id为(object.id)的对象列表和一个id列表。使用ID列表对对象列表排序最有效的方法是什么?我有以下解决方案。。。只是想知道有没有更快的

输入:

  • result
    =具有用户id(user.id)的用户对象列表
  • ID列表
    =用户ID列表,例如
    [3,2,5,8,9]
输出:

  • 根据ID列表排序的用户对象列表
代码:


您可以首先将用户放入dict中:

usrdict = {}
for user in result:
    usrdict[user.id] = user
然后,根据用户的
id
查找用户,您有几个选项,例如:

ordered_result = [usrdict[x] for x in list_of_ids]

编辑:除非您有一个非常大的列表或多次执行该操作,否则我可能不会太担心效率,而是专注于使其清晰易读。

您可以先将用户放入一个目录:

usrdict = {}
for user in result:
    usrdict[user.id] = user
然后,根据用户的
id
查找用户,您有几个选项,例如:

ordered_result = [usrdict[x] for x in list_of_ids]

编辑:除非您有一个非常大的列表或多次执行该操作,否则我可能不会太担心效率,而是专注于使其清晰易读。

您可以使用带有自定义排序功能的
排序功能。在本例中,返回ids列表中的索引

def order_by(objects, ids):
    def fn(obj):
        return ids.index(obj["id"])

    return sorted(objects, key=fn)

print(order_by(objects_list, id_list))
例如:

objects_list = [
{ "id": 3, "name": "penny"},
{ "id": 5, "name": "adam"},
{ "id": 9, "name": "meh"},
{ "id": 1, "name": "john"},
{ "id": 3, "name": "archibald"},
]
id_list = [9,1,3,5,6,4]

print(order_by(objects_list, id_list))
结果:

[{'id': 9, 'name': 'meh'}, {'id': 1, 'name': 'john'}, {'id': 3, 'name': 'penny'}, {'id': 3, 'name': 'archibald'}, {'id': 5, 'name': 'adam'}]

您可以将
排序
功能与自定义排序功能一起使用。在本例中,返回ids列表中的索引

def order_by(objects, ids):
    def fn(obj):
        return ids.index(obj["id"])

    return sorted(objects, key=fn)

print(order_by(objects_list, id_list))
例如:

objects_list = [
{ "id": 3, "name": "penny"},
{ "id": 5, "name": "adam"},
{ "id": 9, "name": "meh"},
{ "id": 1, "name": "john"},
{ "id": 3, "name": "archibald"},
]
id_list = [9,1,3,5,6,4]

print(order_by(objects_list, id_list))
结果:

[{'id': 9, 'name': 'meh'}, {'id': 1, 'name': 'john'}, {'id': 3, 'name': 'penny'}, {'id': 3, 'name': 'archibald'}, {'id': 5, 'name': 'adam'}]
这是一个O(n log(n))解。它要求两个列表中的ID完全相同。它按id对对象列表进行排序,并对id列表进行间接排序,生成一个索引列表,其中按顺序包含id的位置。然后,这将用于将已排序的对象移动到正确的位置

import operator

class know_who_you_are:
    def __init__(self, id_):
        self.id = id_

def argsort(L):
    "returns sorted, order"
    return zip(*sorted(zip(L, range(len(L)))))

ids = [3, 2, 4, 5, 1]
objs = [know_who_you_are(id_) for id_ in [1, 5, 3, 2, 4]]

sid, oid = argsort(ids)
sobj = sorted(objs, key=operator.attrgetter('id'))
result = len(objs) * [None]
for dest, src in zip(oid, sobj):
    result[dest] = src

# check
print(all(id_==obj.id for id_, obj in zip(ids, result)))
印刷品:

True
这是一个O(n log(n))解。它要求两个列表中的ID完全相同。它按id对对象列表进行排序,并对id列表进行间接排序,生成一个索引列表,其中按顺序包含id的位置。然后,这将用于将已排序的对象移动到正确的位置

import operator

class know_who_you_are:
    def __init__(self, id_):
        self.id = id_

def argsort(L):
    "returns sorted, order"
    return zip(*sorted(zip(L, range(len(L)))))

ids = [3, 2, 4, 5, 1]
objs = [know_who_you_are(id_) for id_ in [1, 5, 3, 2, 4]]

sid, oid = argsort(ids)
sobj = sorted(objs, key=operator.attrgetter('id'))
result = len(objs) * [None]
for dest, src in zip(oid, sobj):
    result[dest] = src

# check
print(all(id_==obj.id for id_, obj in zip(ids, result)))
印刷品:

True

下面是一个使用内置函数和自定义比较函数的方案变体。(看起来可能有很多代码,但其中很大一部分只是用于设置一个比较真实的测试用例。)


下面是一个使用内置函数和自定义比较函数的方案变体。(看起来可能有很多代码,但其中很大一部分只是用于设置一个比较真实的测试用例。)


不太清楚你在问什么。结果表,在哪里?你是怎么计算的?@martineau我很确定它不是一个重复的,至少不是你引用的Q。观察这里所需的顺序是如何由一个未排序的列表给出的,这使它成为一个完全不同的问题。特别是,仅仅用属性作为键进行排序并不是一个解决方案。@Paul:你说得对……重新打开了。谢谢。你问的不太清楚。结果表,在哪里?你是怎么计算的?@martineau我很确定它不是一个重复的,至少不是你引用的Q。观察这里所需的顺序是如何由一个未排序的列表给出的,这使它成为一个完全不同的问题。特别是,仅仅用属性作为键进行排序并不是一个解决方案。@Paul:你说得对……重新打开了。谢谢。小心,这里。使用
ids.index(obj[“id”])
是一个O(N)操作,这里要注意排序操作总共O(N^2logn)。使用
ids.index(obj[“id”])
是一个O(N)操作,使排序操作总计为O(N^2logn)