如何在列表中更新Python for循环?

问题描述 投票:1回答:2

在Michael Nielsen的神经网络教程中,他有以下代码:

def update_mini_batch(self, mini_batch, eta):
    """The ``mini_batch`` is a list of tuples ``(x, y)``, and ``eta``
    is the learning rate."""
    nabla_b = [np.zeros(b.shape) for b in self.biases]
    nabla_w = [np.zeros(w.shape) for w in self.weights]
    for x, y in mini_batch:
        delta_nabla_b, delta_nabla_w = self.backprop(x, y)
        nabla_b = [nb+dnb for nb, dnb in zip(nabla_b, delta_nabla_b)]
        nabla_w = [nw+dnw for nw, dnw in zip(nabla_w, delta_nabla_w)]
    self.weights = [w-(eta/len(mini_batch))*nw
                    for w, nw in zip(self.weights, nabla_w)]
    self.biases = [b-(eta/len(mini_batch))*nb
                   for b, nb in zip(self.biases, nabla_b)]

我理解元组和列表是什么,我理解zip函数正在做什么,但我不明白变量nb,dnb,nw和dnw如何在这两行代码上更新:

        nabla_b = [nb+dnb for nb, dnb in zip(nabla_b, delta_nabla_b)]
        nabla_w = [nw+dnw for nw, dnw in zip(nabla_w, delta_nabla_w)]

任何人都可以帮助解释这两行中的魔力吗?

python python-3.x list list-comprehension
2个回答
1
投票

这两行是Python list comprehensions的典型例子。

从本质上讲,您的第一个清单:

nabla_b = [nb+dnb for nb, dnb in zip(nabla_b, delta_nabla_b)]

这意味着:

  1. zip(nabla_b, delta_nabla_b)拿第一对;将它们命名为nbdnb
  2. 添加它们(nb+dnb
  3. 使结果成为新列表nabla_b的第一个元素
  4. 转到第二步,然后将结果附加到nabla_b,直到所有来自zip(nabla_b, delta_nabla_b)的对已经筋疲力尽

举个简单的例子,列表理解如下:

squares = [x**2 for x in range(10)]
print(squares)
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

等效于以下for循环:

squares = []

for x in range(10):
    squares.append(x**2)

print(squares)
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

有关更多示例和快速介绍,请参阅here


1
投票

zip函数将两个列表逐个元素组合在一起,这样如果你给它:

a = [1, 2, 3, 4]
b = ["a", "b", "c", "d"]

zip(a, b)将返回:

[(1, "a"), (2, "b"), ...]

(每个元素都是tuple

你可以使用元素list中每个变量之间的逗号来解压缩tuples(或lists)的tuples元素:

for elem_a, elem_b in zip(a, b):
    print(elem_a, elem_b)

这将打印:

1 a
2 b
3 c
4 d

所以在你的情况下,它添加了两个列表nabla_bdelta_nabla_b elementwise,所以你得到一个列表,每个元素是压缩列表中相应元素的总和。

它可能看起来有点奇怪,因为for循环都在一行上,但这被称为“列表理解”。简单列表理解读起来像英语。

© www.soinside.com 2019 - 2024. All rights reserved.