通过使用内置迭代器和隐式循环阅读这篇关于Python加速循环的wonderful article后,我在我的代码中尝试了它。它在许多部分都运行良好,但是一小部分仍然让我烦恼 - 我迭代的值有时存储为类的字段,这是字典值,我无法摆脱字典上的循环来检索它们。
以下是我的代码的简化版本:
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
个对的半径相加({ {1}}可以是整个字典)。是否有任何“广播”技术,或标记线中的循环是不可避免的?
顺便说一句 - 我是初学者,因此任何关于代码的有用评论(包括样式和Python)都将受到赞赏。
谢谢!
答案 0 :(得分:1)
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)
我无法通过字典循环来检索它们。
重读你的代码!您没有循环遍历字典,而是在 sub_list 上进行迭代!也许这是一个语法问题,在这里你可以重写那个迭代:
values=[]
for ind in sub_list:
values.append(d[x, y])
考虑一下,你想要的是获得子列表中每个元素的预先计算的半径值。所以除了迭代子列表之外别无他法!无论您是使用列表理解还是使用地图,这都是个人偏好的问题,即使列表理解更有效:
>>> 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)
!