Объедините несколько объектов и создайте список перекрывающихся атрибутов в Python - PullRequest
0 голосов
/ 04 сентября 2018

У меня есть класс, подобный следующему:

class test(object):
    def __init__(self, ID, A, B, C, D, E):
        self.ID = ID
        self.A = A
        self.B = B
        self.C = C
        self.D = D
        self.E = E

И несколько объектов в списке:

test1 = test(6124, 6, 'Tim', 'Football', 'Soccer', 'USA')
test2 = test(6124, 7, 'Joe', 'Basketball', 'Soccer', 'USA')
test3 = test(6188, 8, 'Joe', 'Basketball', 'Soccer', 'USA')
test4 = test(6188, 9, 'Joe', 'Basketball', 'Soccer', 'USA')
test5 = test(6188, 10, 'Tim', 'Football', 'Soccer', 'USA')

objects_list = [test1, test2, test3, test4, test5]

Я хочу объединить эти объекты на основе их атрибута ID, а для остальных атрибутов просто составить список отдельных объектов:

Для этого примера результатом будут два объекта (как только два уникальных идентификатора), один из которых будет иметь атрибуты:

self.ID = 6124
self.A = [6, 7]
self.B = ['Tim', 'Joe']
self.C = ['Football', 'Basketball']
self.D = ['Soccer', 'Soccer']
self.E = ['USA', 'USA]

Как я могу объединить объекты в списке таким образом? Я ищу решение, которое не требует, чтобы я называл какие-либо атрибуты, кроме имени атрибута, с которым я объединяюсь (ID). Было бы очень хорошо, если бы это решение можно было обобщить для объединения нескольких атрибутов одновременно (скажем, ID и A и E).

Спасибо! Jack

1 Ответ

0 голосов
/ 05 сентября 2018

Попробуйте это решение:

from operator import attrgetter
from itertools import groupby


class Test(object):
    def __init__(self, ID, A, B, C, D, E):
        self.ID = ID
        self.A = A
        self.B = B
        self.C = C
        self.D = D
        self.E = E


test1 = Test(6124, 6, 'Tim', 'Football', 'Soccer', 'USA')
test2 = Test(6124, 7, 'Joe', 'Basketball', 'Soccer', 'USA')
test3 = Test(6188, 8, 'Joe', 'Basketball', 'Soccer', 'USA')
test4 = Test(6188, 9, 'Joe', 'Basketball', 'Soccer', 'USA')
test5 = Test(6188, 10, 'Tim', 'Football', 'Soccer', 'USA')

objects_list = [test1, test2, test3, test4, test5]

# get names of attributes except 'ID'
attrs = list(x for x in dir(test1) if not x.startswith('__') and x != 'ID')

# iterate through grouped by 'ID' elements
for id_, group in groupby(sorted(objects_list, key=attrgetter('ID')),
                          key=attrgetter('ID')):
    # create result object with lists as attributes
    result = Test(id_, *[[]]*len(attrs))

    # merge elements
    for x in group:
        for a in attrs:
            setattr(result, a, getattr(result, a) + [getattr(x, a)])

    print(result.ID, result.A, result.B, result.C, result.D, result.E)

Результат:

6124 [6, 7] ['Tim', 'Joe'] ['Football', 'Basketball'] ['Soccer', 'Soccer'] ['USA', 'USA']
6188 [8, 9, 10] ['Joe', 'Joe', 'Tim'] ['Basketball', 'Basketball', 'Football'] ['Soccer', 'Soccer', 'Soccer'] ['USA', 'USA', 'USA']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...