Как эффективно сгруппировать два списка объектов класса на основе атрибута в Python? - PullRequest
0 голосов
/ 17 апреля 2020

У меня есть два списка, которые оба содержат объекты из одного класса. Я хочу сгруппировать их в третий список, который содержит списки или кортежи объектов с одинаковым значением атрибута.

Пример

Object1.time = 1 
Object2.time = 2
Object3.time = 1
Object4.time = 2
Objekt5.time = 3


list1 = [Object1, Object2]
list2 = [Object3,Object4]

Там результат сортировки должен выглядеть следующим образом:

result_list = [[Object1,Object3], [Object2,Object4], [Object5]]

Мне нужно упомянуть: мне не нужны списки, содержащие только один объект!

, поэтому окончательный список должен выглядеть следующим образом:

final_result = [[Objekt1, Objekt3], [Objekt2, Objekt4]]

List1 содержит 1500 объектов, List2 - более 70000 Проблема: если я использую два цикла for для сравнения объектов, это занимает слишком много времени.

Вот мой неэффективный пример:

class Example:
    def __init__(self,time,example_attribute):
        self.time = time
        self.example_attribute = example_attribute

test_list1 = [1,1,2,3,4,5,6,6,7,8,9,9]
test_list2 = ["a","b","c","d","e","f","d","e","f","g","h","i"]

test_list3 = ["j","k","l","m","n","o","p","q","r","s","t","u"]


object_list1 = []
for i,j in zip(test_list1,test_list2):
    object_list1.append(Example(i,j))

object_list2 = []
for i,j in zip(test_list1,test_list3):
    object_list2.append(Example(i,j))


# How to group both lists together by the time attribute? This part takes too long.
group_by_time = []
for i in object_list1:
    my_list = [i]
    for j in object_list2:
        if i.time == j.time:
            my_list.append(j)
    group_by_time.append(my_list)

for sub_list in group_by_time:
    for index, item in enumerate(sub_list):
        if index == 0:
            print(item.time, ",",item.example_attribute,end =",")
        else:print(item.example_attribute, end = ",")
    print("")```

1 Ответ

3 голосов
/ 17 апреля 2020

Используйте словарь, который идиоматически группирует вещи:

import itertools

grouped = {}
for obj in itertools.chain(list1, list2):
    grouped.setdefault(obj.time, []).append(obj)

Теперь у вас есть словарь, отображающий атрибут времени в список объектов. Вы можете получить список списка, если вы действительно хотите, что-то вроде:

final = list(grouped.values())

Если вы хотите опустить списки только с одним значением, вы можете сделать что-то вроде:

final = [v for v in grouped.values() if len(v) > 1]
...