Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从python3中具有多个属性的对象列表中提取多个属性列表_Python_List Comprehension - Fatal编程技术网

从python3中具有多个属性的对象列表中提取多个属性列表

从python3中具有多个属性的对象列表中提取多个属性列表,python,list-comprehension,Python,List Comprehension,我有一个类a,有多个字段a,b,c。我有一个此类a的对象列表。现在,我想提取3个列表,首先包含所有对象中字段a的值,第二个列表包含字段b的值,第三个列表包含字段c的值 我找到了以下答案 答案是我可以使用下面的列表理解 a_list=[obj.a for obj in obj_list] 答案是用来保存记忆 a_list=(obj.a for obj in obj_list) 现在,我的问题是,当我想要提取多个属性时,这是否有效?如果我把这行写三次,如下所示 a_list=(obj.a for

我有一个类
a
,有多个字段
a
b
c
。我有一个此类
a
的对象列表。现在,我想提取3个列表,首先包含所有对象中字段
a
的值,第二个列表包含字段
b
的值,第三个列表包含字段
c
的值

我找到了以下答案
答案是我可以使用下面的列表理解

a_list=[obj.a for obj in obj_list]
答案是用来保存记忆

a_list=(obj.a for obj in obj_list)
现在,我的问题是,当我想要提取多个属性时,这是否有效?如果我把这行写三次,如下所示

a_list=(obj.a for obj in obj_list)
b_list=(obj.b for obj in obj_list)
c_list=(obj.c for obj in obj_list)
我将对列表进行三次迭代。这不是很贵吗?在这种情况下,使用for循环更好吗

for obj in obj_list:
    a_list.append(obj.a)
    b_list.append(obj.b)
    c_list.append(obj.c)
哪个更快?这是一个更好的方法。还有其他更好的优化方法吗? 谢谢

任何时候你认为“X比Y快”你都需要测量

你可以想出一个办法,不让你的名单三次通过

然而,这种“方式”可能仍然不会更快,因为它使整个代码更加复杂,计算成本也更高

不浏览对象trice列表的一种方法是利用zip和map,如下所示:

class O:
    def __init__(self,a,b,c):
        self.a=a
        self.b=b
        self.c=c
    def __str__(self):
        return f"#{self.a} {self.b} {self.c}#"
    def __repr__(self): return str(self)

obj = [O(a,a**4,1.0/a) for a in range(2,20)]

print(obj)

# use a generator to make 3-tuples of your classes attributes and decompose 
# those into zip which builds your lists
a,b,c  = map(list, zip( *((e.a,e.b,e.c) for e in obj)) )

print(a,b,c )
对象:

[#2 16 0.5#, #3 81 0.3333333333333333#, #4 256 0.25#, #5 625 0.2#, 
 #6 1296 0.16666666666666666#, #7 2401 0.14285714285714285#, #8 4096 0.125#,
 #9 6561 0.1111111111111111#, #10 10000 0.1#, #11 14641 0.09090909090909091#, 
 #12 20736 0.08333333333333333#, #13 28561 0.07692307692307693#, 
 #14 38416 0.07142857142857142#, #15 50625 0.06666666666666667#, 
 #16 65536 0.0625#, #17 83521 0.058823529411764705#, 
 #18 104976 0.05555555555555555#, #19 130321 0.05263157894736842#]
结果:

[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] 

[16, 81, 256, 625, 1296, 2401, 4096, 6561, 10000, 14641, 20736, 28561, 
 38416, 50625, 65536, 83521, 104976, 130321] 

[0.5, 0.3333333333333333, 0.25, 0.2, 0.16666666666666666, 0.14285714285714285, 
 0.125, 0.1111111111111111, 0.1, 0.09090909090909091, 0.08333333333333333,
 0.07692307692307693, 0.07142857142857142, 0.06666666666666667, 0.0625, 
 0.058823529411764705, 0.05555555555555555, 0.05263157894736842]
7.969175090000135  # map + zip
5.124133489000087  # simple loop
你仍然需要测量这是否比通过一个物体列表更快

即使18个元素的速度较慢,200万个元素的速度也可能更快。因此,使用什么是非常具体的


时间:

s = """
class O:
    def __init__(self,a,b,c):
        self.a=a
        self.b=b
        self.c=c
    def __str__(self):
        return f"#{self.a} {self.b} {self.c}#"
    def __repr__(self): return str(self)

# changed to ** 2 instead of 4
# changed to 200 elements
obj = [O(a,a**2,1.0/a) for a in range(2,200)] 
"""

code1="""
a,b,c  = map(list,zip( *((e.a,e.b,e.c) for e in obj))  )
"""
code2="""
a1 = [e.a for e in obj]
b1 = [e.b for e in obj]
c1 = [e.c for e in obj]
"""

from timeit import timeit

print(timeit(code1,setup=s,number=100000))
print(timeit(code2,setup=s,number=100000))
结果:

[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] 

[16, 81, 256, 625, 1296, 2401, 4096, 6561, 10000, 14641, 20736, 28561, 
 38416, 50625, 65536, 83521, 104976, 130321] 

[0.5, 0.3333333333333333, 0.25, 0.2, 0.16666666666666666, 0.14285714285714285, 
 0.125, 0.1111111111111111, 0.1, 0.09090909090909091, 0.08333333333333333,
 0.07692307692307693, 0.07142857142857142, 0.06666666666666667, 0.0625, 
 0.058823529411764705, 0.05555555555555555, 0.05263157894736842]
7.969175090000135  # map + zip
5.124133489000087  # simple loop

我认为for循环会更快,但是如果obj_列表真的很大,你别无选择,只能使用生成器,因为我们不能在rami中存储3个大小为
len(obj_列表)
的列表在我的情况下,obj_列表最多可以有10个元素。