Zip with the layers and a slice of layers that begins with the second item. Note that zip()
will stop as soon as any of its iterables are exhausted.
for L0, L1 in zip(layers, layers[1:]):
weights[L0] = np.random.rand(
L1.node_cardinality,
L0.node_cardinality + 1
)
Depending on what type of sequence layers
is, it may be more efficient to use an itertools.islice
instead of a normal slice. A numpy array will probably just use a view if you slice. But a list would have to create a (shallow) copy, so an islice is better if it's very long.
for L0, L1 in zip(layers, islice(layers, 1, None)):
weights[L0] = np.random.rand(
L1.node_cardinality,
L0.node_cardinality + 1
)
As GrazingScientist has pointed out, this could also be done with a dict comprehension.
weights.update(
{
L0: np.random.rand(L1.node_cardinality, L0.node_cardinality + 1)
for L0, L1 in zip(layers, layers[1:])
}
)
But this approach will have to generate a new dict before updating, which may take more memory. The for loop is probably better if layers
is long. But dicts only contain references, so it's probably not much worse than using a normal list slice is.
It would actually be more efficient to use a generator expression in this case. The .update()
method can also accept an iterable of (k, v)
pairs, but a generator doesn't have to allocate them all at once. It just does a pair at a time.
weights.update(
(L0, np.random.rand(L1.node_cardinality, L0.node_cardinality + 1))
for L0, L1 in zip(layers, islice(layers, 1, None))
)