【问题标题】:How can I assign each varying value of a list to different keys of the same dictionary?如何将列表的每个不同值分配给同一字典的不同键?
【发布时间】:2019-10-08 23:25:48
【问题描述】:

我正在尝试创建一个字典(sums),其键是列表的总和,值是列表本身。此列表具有不同数量的元素,但名称相同。每次更改列表的元素并将此更改的列表(相同名称)分配给不同的键时,先前分配给键的值也会更改。

在寻找合适的答案时,我从这里 (https://stackoverflow.com/a/52806573/7198441) 了解到,这可能是因为 Python 也引用了列表(如果我在这里出错,请纠正我)。现在,我想知道,是否有一种方法可以将具有相同名称但在不同迭代阶段的不同元素的列表分配给同一字典的不同键。

l = [1, 2, 3, 4, 5]

sums = {}

while len(l) :

    l_sum = sum(l)
    sums[l_sum] = l

    print(sums)
    print()

    l.pop()

实际结果:

{15: [1, 2, 3, 4, 5]}

{15: [1, 2, 3, 4], 10: [1, 2, 3, 4]}

{15: [1, 2, 3], 10: [1, 2, 3], 6: [1, 2, 3]}

{15: [1, 2], 10: [1, 2], 6: [1, 2], 3: [1, 2]}

{15: [1], 10: [1], 6: [1], 3: [1], 1: [1]}

预期:

{15: [1, 2, 3, 4, 5]}

{15: [1, 2, 3, 4, 5], 10: [1, 2, 3, 4]}

{15: [1, 2, 3, 4, 5], 10: [1, 2, 3, 4], 6: [1, 2, 3]}

{15: [1, 2, 3, 4, 5], 10: [1, 2, 3, 4], 6: [1, 2, 3], 3: [1, 2]}

{15: [1, 2, 3, 4, 5], 10: [1, 2, 3, 4], 6: [1, 2, 3], 3: [1, 2], 1: [1]}

【问题讨论】:

    标签: python list dictionary python-3.7


    【解决方案1】:

    问题在于,当您执行sums[l_sum] = l 时,您正在使用对原始列表的引用。因此,在 while 循环的任何步骤中的所有更改都会影响使用此列表的所有其他地方。这就是为什么您会在每次打印中看到您的列表发生变化的原因。

    简单的解决方案是使用sums[l_sum] = l[:]复制列表。


    while len(l) :
        l_sum = sum(l)
        sums[l_sum] = l[:] # <--- changed here from l to l[:]
        print(sums)
        print()
        l.pop()
    
    # {15: [1, 2, 3, 4, 5]}
    
    # {15: [1, 2, 3, 4, 5], 10: [1, 2, 3, 4]}
    
    # {15: [1, 2, 3, 4, 5], 10: [1, 2, 3, 4], 6: [1, 2, 3]}
    
    # {15: [1, 2, 3, 4, 5], 10: [1, 2, 3, 4], 6: [1, 2, 3], 3: [1, 2]}
    
    # {15: [1, 2, 3, 4, 5], 10: [1, 2, 3, 4], 6: [1, 2, 3], 3: [1, 2], 1: [1]}
    

    【讨论】:

      【解决方案2】:

      您正在对列表对象的一个​​实例执行所有操作。这就是为什么在最终结果中您会得到所有值的相同列表。而不是循环,作为一种更 Pythonic 的方式,您可以使用字典理解或 itertools.accumulate 来获取列表项的累积总和,然后使用 zip 创建您预期的字典。

      In [13]: {sum(l[:i + 1]): l[:i + 1] for i in range(len(l))}
      Out[13]: {1: [1], 3: [1, 2], 6: [1, 2, 3], 10: [1, 2, 3, 4], 15: [1, 2, 3, 4, 5]}
      

      或者(不那么 Pythonic):

      In [7]: dict(zip(accumulate(l), [l[:i + 1] for i in range(len(l))]))
      Out[7]: {1: [1], 3: [1, 2], 6: [1, 2, 3], 10: [1, 2, 3, 4], 15: [1, 2, 3, 4, 5]}
      

      【讨论】:

      • 我很欣赏@Kasrâmvd 的回答质量,但我一直在寻找我接受的解决方案。谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多