【问题标题】:How to iterate over dictionary in Python whose (k,v) pair uses consecutive items from a list如何在 Python 中迭代其(k,v)对使用列表中的连续项目的字典
【发布时间】:2019-03-04 06:34:41
【问题描述】:

我想将(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() 代码?

【问题讨论】:

  • 如果你使用 python 3,在 mydict.items() 中使用 k, v,如果你使用 python 2,在 mydict.iteritems() 中使用 k, v
  • @Nico238 这不是基本的 items() 迭代。

标签: python loops dictionary range key


【解决方案1】:

压缩图层和从第二个项目开始的图层切片。请注意,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 循环可能会更好。但是 dicts 只包含引用,所以它可能并不比使用普通的列表切片差多少。

在这种情况下使用生成器表达式实际上会更有效。 .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))
)

【讨论】:

    【解决方案2】:

    我建议使用enumeratedict 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。

    【讨论】:

      猜你喜欢
      • 2014-02-13
      • 1970-01-01
      • 1970-01-01
      • 2011-02-01
      • 1970-01-01
      • 2012-09-14
      • 2014-09-26
      • 2021-08-19
      相关资源
      最近更新 更多