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

时间:2019-02-14 14:36:17

标签: python python-3.x list list-comprehension

在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)]

有人能帮助解释这两行中发生的魔术吗?

2 个答案:

答案 0 :(得分:1)

zip函数将两个列表逐个元素地粘贴在一起,因此,如果给了它:

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

zip(a, b)将返回:

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

(每个元素均为tuple

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

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,因此您将获得一个列表,每个元素都是压缩列表中相应元素的总和。

这看起来可能有点奇怪,因为for循环全部在一行上,但这称为“列表理解”。简单的列表理解就像英语一样。

答案 1 :(得分:1)

这两行是Python https://url.com的典型示例。

本质上,对于您的第一个列表:

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]

有关更多示例和快速介绍,请参见list comprehensions