Список объектов: эффективное получение списка суммы атрибута ith - PullRequest
0 голосов
/ 26 мая 2018

Извините, если название озадачивает, я не знаю, как правильно сформулировать эту проблему.

Я довольно новичок в программировании за пределами классовых проектов / работ, и я пытаюсь разработатьхорошие привычки программирования, и избегайте циклов, где я могу (т.е. держаться подальше от неэффективного кода).Проект, над которым я работаю, включает получение списка сумм атрибута ith из списка объектов, и мне удалось что-то сделать с помощью карт, но мне интересно, есть ли лучший способ сделать это.

Скажем, я работаю с классом Foo, с n атрибутами, a1, a2, ..., an, всеми целыми числами и списком l, содержащим m из этих объектов.

Например, для n = 3 у нас может быть что-то вроде:

l = [Foo(a1 = 1, a2 = 2, a3 = 3), Foo(a1 = 1, a2 = 2, a3 = 3), Foo(a1 = 1, a2 = 2, a3 = 3)]

Я хочу, чтобы мой результат выглядел следующим образом:

sums = [3, 6, 9]

Я сделал это так:

sums = [sum([x.a1 for x in l]),
        sum([x.a2 for x in l]), 
        sum([x.a3 for x in l])]

Теперь проблема в том, что если Foo имеет много атрибутов, то ввод каждого x.an может оказаться невозможным.К атрибутам необязательно также присоединено целое число, поэтому они могут быть такими, как Foo(these, are, some, attributes).

Итак, мой вопрос: каков «умный» способ решения этой проблемы?Включает ли это использование цикла?Спасибо.

Ответы [ 2 ]

0 голосов
/ 26 мая 2018

Вы можете использовать модуль inspect для извлечения списка всех аргументов, необходимых для инициализации экземпляра класса.

Затем итерируйте эти аргументы со списком:

import inspect

class Foo():
    def __init__(self, a1, a2, a3):
        self.a1 = a1
        self.a2 = a2
        self.a3 = a3
        pass

# get list of arguments, ignore the first which is self
args = inspect.getfullargspec(Foo.__init__).args[1:]

l = [Foo(a1=1, a2=2, a3=3), Foo(a1=1, a2=2, a3=3), Foo(a1=1, a2=2, a3=3)]

# use list comprehension to sum by attribute
sums = [sum([getattr(x, i) for x in l]) for i in args]

# [3, 6, 9]
0 голосов
/ 26 мая 2018

Основная идея заключается в использовании встроенной функции getattr , которая возвращает значение атрибута, используя его имя:

class Foo:
    def __init__(self,a1,a2,a3):
        self.a1 = a1
        self.a2 = a2
        self.a3 = a3

l = [Foo(a1 = 1, a2 = 2, a3 = 3), Foo(a1 = 1, a2 = 2, a3 = 3), Foo(a1 = 1, a2 = 2, a3 = 3)]

sums = [sum([getattr(x,'a{}'.format(i)) for x in l]) for i in range(1,4)]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...