任何时候你认为“isX快于Y”时,你需要测量。在
你可以想出一种方法来避免三次通过你的名单。在
然而,这种“方法”可能仍然不够快,因为它使整个代码更加复杂,计算成本也很高。在
一种不必查看对象列表的方法是利用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 )
对象:
^{pr2}$
结果:[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]
你还是要测量一下,这是否比浏览一系列物体要快。在
即使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))
结果:7.969175090000135 # map + zip
5.124133489000087 # simple loop