【问题标题】:How to iterate over a list that has duplicate values?如何遍历具有重复值的列表?
【发布时间】:2019-10-13 16:48:14
【问题描述】:

这可能是一个非常基本的问题,但我不知道我必须搜索什么才能找到答案:

我有这个代码:

list = [[0,1],[0,2],[1,3],[1,4],[1,5]]

list.append(list[0])

for i in list:
    i.append(0)

print(list)

此列表稍后将用作曲线的坐标。我需要在最后复制第一个坐标以获得闭合曲线。

如果我想为列表中的每个坐标添加第三个值,则列表中的第一项和最后一项将被迭代两次:

[[0, 1, 0, 0], [0, 2, 0], [1, 3, 0], [1, 4, 0], [1, 5, 0], [0, 1, 0, 0]]

我猜它们具有相同的内存地址,因此附加函数应用于此地址的同一对象,一次用于第一个索引,一次用于最后一个索引。

这种现象叫什么?获得这样的列表的最简单方法是什么:

[[0, 1, 0], [0, 2, 0], [1, 3, 0], [1, 4, 0], [1, 5, 0], [0, 1, 0]]

感谢您的帮助

【问题讨论】:

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


    【解决方案1】:

    你可以做一个列表理解:

    list = [[0,1],[0,2],[1,3],[1,4],[1,5]]
    
    list.append(list[0])
    list = [x + [0] for x in list]
    
    print(list)
    # [[0, 1, 0], [0, 2, 0], [1, 3, 0], [1, 4, 0], [1, 5, 0], [0, 1, 0]]
    

    编辑:这里的技巧是,在列表理解中使用x + [0]。这样就创建了新列表,因此您不会将 0 附加到同一个列表两次(Hattip to @dx_over_dt)

    您的方法存在的问题是,列表的第一个和最后一个元素引用的是同一个对象。当您为每次迭代打印 i 和 list 时,您可以看到这一点:

    for i in list:
         i.append(0)
         print(i)
         print(list)
    

    因此,对于循环中的第一个和最后一个 i,您将在同一个列表中附加一个 0。 您可以坚持使用附加第一个元素的副本的方法:

    list.append(list[0].copy())
    

    【讨论】:

    • 这行得通,谢谢。但是,我认为列表推导式只是一种更有效的 for 循环编写方式。但是迭代的方式不同吗?
    • 另外,列表解析会生成新对象,这就是它正常工作的原因。
    • 我明白了,非常感谢!
    • Afaik,由于 + 运算符,它只会生成新对象。 [x for x in list]我相信不会创建新对象。如果您有一个附加元素并返回列表而不是使用 + 的函数,我相信您将具有与 for 循环相同的行为。就此而言,您原来的 for 循环可以完成 for i in range(len(list)): list[i] = list[i] + [0]
    【解决方案2】:

    最简单的答案是在附加结束点之前添加 0。

    list = [[0,1],[0,2],[1,3],[1,4],[1,5]]
    
    for i in list:
        i.append(0)
    
    list.append(list[0])
    
    print(list)
    

    它比列表推导效率稍微高一点,因为它不会复制元素。

    【讨论】:

    • 确实如此,但是,在我的实际代码中,追加发生在不同的位置,因为我还需要没有第三个值但第一个项目在末尾的坐标。
    猜你喜欢
    • 1970-01-01
    • 2013-08-19
    • 1970-01-01
    • 1970-01-01
    • 2019-11-18
    • 2014-07-06
    • 2021-06-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多