我想将(k,v)
对添加到字典weights
中,其中该字典的键等于列表layers
中的对象。该值的构造使得它使用此列表中的对象l
和对象l+1
。我目前这样做如下:
layers = self.layers
for l in range(0, layers.__len__() - 1):
weights[layers[l]] = np.random.rand(
layers[l + 1].node_cardinality,
layers[l].node_cardinality + 1
)
是否有一种更好,更短的方法而不必使用range()
代码?
答案 0 :(得分:2)
以第二个项目开头的层和层的切片作为邮政编码。请注意,zip()
将在其所有可迭代项用尽后立即停止。
for L0, L1 in zip(layers, layers[1:]):
weights[L0] = np.random.rand(
L1.node_cardinality,
L0.node_cardinality + 1
)
根据序列layers
的类型,使用itertools.islice
代替普通切片可能会更有效。如果进行切片,则numpy数组可能只会使用视图。但是列表必须创建一个(浅)副本,因此,如果长度很长,则islice更好。
for L0, L1 in zip(layers, islice(layers, 1, None)):
weights[L0] = np.random.rand(
L1.node_cardinality,
L0.node_cardinality + 1
)
正如GrazingScientist指出的那样,也可以通过字典理解来完成。
weights.update(
{
L0: np.random.rand(L1.node_cardinality, L0.node_cardinality + 1)
for L0, L1 in zip(layers, layers[1:])
}
)
但是这种方法必须在更新之前生成一个新的字典,这可能会占用更多的内存。如果layers
长,则for循环可能会更好。但是字典仅包含引用,因此它可能并不比使用普通列表切片差很多。
在这种情况下,使用生成器表达式实际上会更有效。 .update()
方法还可以接受(k, v)
对的可迭代对象,但是生成器不必一次分配它们。一次只做一对。
weights.update(
(L0, np.random.rand(L1.node_cardinality, L0.node_cardinality + 1))
for L0, L1 in zip(layers, islice(layers, 1, None))
)
答案 1 :(得分:0)
我建议使用enumerate和dict comprehension。这是更pythonic的,可能更快。
layers = self.layers
buf_dict = {layers[i]: np.random.rand(layers[i + 1].node_cardinality, layers[i].node_cardinality + 1)
for i, l in zip(layers, layers[1:])}
weights.update(buf_dict)
编辑:忘记了代码,并确认zip在这种情况下实际上比枚举更好(这要感谢gilch),因为您不会遇到IndexError。