如果标题令人困惑,我很抱歉,我不知道如何真正说出这个问题。
我在课堂项目/工作之外编程相当新,我正在努力培养良好的编程习惯,并尽可能避免循环(即远离低效的代码)。我正在研究的一个项目涉及从一个对象列表中获取一个ith属性的总和列表,我设法用地图理解做了一些事情,但我想知道是否有更好的方法来做它。
说我正在使用类Foo
,包含n个属性,a1
,a2
,...,an
,所有整数和列表{ {1}}包含m个这些对象。
例如,对于l
,我们可以使用类似的内容:
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
之类的东西。
所以,我的问题是,解决这个问题的“智能”方法是什么?它是否涉及使用循环?谢谢。
答案 0 :(得分:2)
您可以使用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]
答案 1 :(得分:0)
主要思想是使用 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)]