看完这篇wonderful article关于通过使用内置迭代器和隐式循环在 Python 中加速循环 我已经在我的代码中尝试过了。它在很多方面都运行良好,但一小部分仍然让我很烦——我迭代的值有时存储为一个类的字段,这些字段是字典值,我无法摆脱循环遍历我的字典来检索它们。
这是我的代码的简化版本:
class Pair:
def __init__(self):
self.radius = 0.0
indices = [(x, y) for y in range(5) for x in range(5)]
d = {}
for (x, y) in indices:
d[x, y] = Pair()
d[x, y].radius = (x ** 2 + y ** 2) ** 0.5
sub_list = [(1, 2), (2, 3), (3, 4)]
values = [d[ind].radius for ind in sub_list] # <-- main problem
print reduce(lambda x, y: x + y, values)
所以字典 d
有元组 (x, y)
作为键,Pair
实例作为值,我的目标是求和给定 sub_list
对的半径(sub_list
可以是整个字典)。是否有任何“广播”技术,或者标记行中的循环是不可避免的?
顺便说一句 - 我是初学者,所以任何关于代码的有用评论(包括样式和 Pythonish 将不胜感激。
谢谢!
最佳答案
好吧,你的代码还不错,尽管有一个没用的东西,就是你的对象 Pair。您也可以将半径作为值存储在字典中:
indices = [(x, y) for y in range(5) for x in range(5)]
sub_list = [(1, 2), (2, 3), (3, 4)]
d = {}
for (x, y) in indices:
d[x, y] = (x ** 2 + y ** 2) ** 0.5
values = [d[ind] for ind in sub_list] # <-- no problem
print reduce(lambda x, y: x + y, values)
I can't get rid of looping over my dictionary to retrieve them.
重读你的代码!您不是在遍历字典,而是在遍历 sub_list!也许这是一个语法问题,这里是您可以重写该迭代的方法:
values=[]
for ind in sub_list:
values.append(d[x, y])
想一想,您想要的是为子列表的每个元素获取预先计算的半径值。所以实际上除了遍历子列表别无他法!您是使用列表推导式还是 map 来执行此操作主要取决于个人喜好,即使列表推导式更有效:
>>> timeit.repeat(lambda: [d[ind] for ind in sub_list])
[0.8207108974456787, 0.8075330257415771, 0.788733959197998]
>>> timeit.repeat(lambda: map(lambda ind: d[ind], sub_list))
[1.6066839694976807, 1.630357027053833, 1.755575180053711]
如果您谈论复杂性,请考虑 d
的大小为 m
,values
之一为 n
,然后:
values = [d[ind] for ind in sub_list]
是 O(n)
!
关于python - 检索存储在字典中的类实例的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23579946/