gpt4 book ai didi

python - Django/Python - 通过多对多关系中的公共(public)集对对象进行分组

转载 作者:太空狗 更新时间:2023-10-29 21:41:20 24 4
gpt4 key购买 nike

这部分是算法逻辑问题(如何做),部分是实现问题(如何做到最好!)。我正在使用 Django,所以我想我会分享一下。

在 Python 中,值得一提的是这个问题与 how-do-i-use-pythons-itertoolsgroupby 有点相关。 .

假设您有两个 Django 模型派生类:

from django.db import models

class Car(models.Model):
mods = models.ManyToManyField(Representative)

from django.db import models

class Mods(models.Model):
...

如何获得按具有一组通用 Mod 的汽车分组的汽车列表?

即我想上这样的课:

Cars_by_common_mods = [ 
{ mods: { 'a' }, cars: { 'W1', 'W2' } },
{ mods: { 'a', 'b' }, cars: { 'X1', 'X2', 'X3' }, },
{ mods: { 'b' }, cars: { 'Y1', 'Y2' } },
{ mods: { 'a', 'b', 'c' }, cars: { 'Z1' } },
]

我一直在想这样的事情:

def cars_by_common_mods():
cars = Cars.objects.all()

mod_list = []

for car in cars:
mod_list.append( { 'car': car, 'mods': list(car.mods.all()) }

ret = []

for key, mods_group in groupby(list(mods), lambda x: set(x.mods)):
ret.append(mods_group)

return ret

但是,这不起作用,因为(可能还有其他原因)groupby 似乎没有按 mods 集分组。我想必须对 mod_list 进行排序才能与 groupby 一起使用。总而言之,我相信那里有一些简单而优雅的东西,它们既有启发性又有启发性。

干杯,谢谢!

最佳答案

您是否尝试过先对列表进行排序?您提出的算法应该可以工作,尽管有很多数据库命中。

import itertools

cars = [
{'car': 'X2', 'mods': [1,2]},
{'car': 'Y2', 'mods': [2]},
{'car': 'W2', 'mods': [1]},
{'car': 'X1', 'mods': [1,2]},
{'car': 'W1', 'mods': [1]},
{'car': 'Y1', 'mods': [2]},
{'car': 'Z1', 'mods': [1,2,3]},
{'car': 'X3', 'mods': [1,2]},
]

cars.sort(key=lambda car: car['mods'])

cars_by_common_mods = {}
for k, g in itertools.groupby(cars, lambda car: car['mods']):
cars_by_common_mods[frozenset(k)] = [car['car'] for car in g]

print cars_by_common_mods

现在,关于那些查询:

import collections
import itertools
from operator import itemgetter

from django.db import connection

cursor = connection.cursor()
cursor.execute('SELECT car_id, mod_id FROM someapp_car_mod ORDER BY 1, 2')
cars = collections.defaultdict(list)
for row in cursor.fetchall():
cars[row[0]].append(row[1])

# Here's one I prepared earlier, which emulates the sample data we've been working
# with so far, but using the car id instead of the previous string.
cars = {
1: [1,2],
2: [2],
3: [1],
4: [1,2],
5: [1],
6: [2],
7: [1,2,3],
8: [1,2],
}

sorted_cars = sorted(cars.iteritems(), key=itemgetter(1))
cars_by_common_mods = []
for k, g in itertools.groupby(sorted_cars, key=itemgetter(1)):
cars_by_common_mods.append({'mods': k, 'cars': map(itemgetter(0), g)})

print cars_by_common_mods

# Which, for the sample data gives me (reformatted by hand for clarity)
[{'cars': [3, 5], 'mods': [1]},
{'cars': [1, 4, 8], 'mods': [1, 2]},
{'cars': [7], 'mods': [1, 2, 3]},
{'cars': [2, 6], 'mods': [2]}]

现在您已经有了汽车 ID 和 retrofit ID 的列表,如果您需要使用完整的对象,您可以对每个对象执行一个查询以获得每个模型的完整列表并创建一个查找 dict 对于那些以他们的 id 为键的人 - 那么,我相信,Bob 就是你众所周知的父亲的兄弟。

关于python - Django/Python - 通过多对多关系中的公共(public)集对对象进行分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/160298/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com