【问题标题】:Changing a certain index of boolean list of lists change others, too [duplicate]更改布尔列表的某个索引也会改变其他列表[重复]
【发布时间】:2018-04-01 13:29:46
【问题描述】:

所以我有一个布尔列表,我将某个索引从 True 更改为 False,它也会影响列表列表中的其他一些元素。为什么会这样?有没有其他选择?

test = [[True]*9]*9
test[0][1] = False
print(test)

输出:

[[True, False, True, True, True, True, True, True, True], 
[True, False, True, True, True, True, True, True, True], 
[True, False, True, True, True, True, True, True, True], 
[True, False, True, True, True, True, True, True, True], 
[True, False, True, True, True, True, True, True, True], 
[True, False, True, True, True, True, True, True, True], 
[True, False, True, True, True, True, True, True, True], 
[True, False, True, True, True, True, True, True, True], 
[True, False, True, True, True, True, True, True, True]]

【问题讨论】:

    标签: python python-3.x list boolean


    【解决方案1】:

    你想做的是:

    test = [[True for i in range(cols)] for j in range(rows)]
    #OR
    test = [[True]*cols for j in range(rows)]
    

    做的问题

    test = [[True]*9]*9
    

    是您正在创建一个multi-dimensional list,它引用了包含True 值的same memory address

    这就像拥有:

    test = [ [True, True, True, True, True, True, True, True, True] repeated 9 times ]
    

    所有行都指向它们各自列的相同内存位置。因此,当您更改一列中的值时,它会更改整个列值。

    所以,用想要的方式,

    test = [[True for i in range(9)] for j in range(9)]
    test[0][1] = False
    print(test)
    

    将打印:

    [[True, False, True, True, True, True, True, True, True], 
    [True, True, True, True, True, True, True, True, True], 
    [True, True, True, True, True, True, True, True, True], 
    [True, True, True, True, True, True, True, True, True], 
    [True, True, True, True, True, True, True, True, True], 
    [True, True, True, True, True, True, True, True, True], 
    [True, True, True, True, True, True, True, True, True], 
    [True, True, True, True, True, True, True, True, True], 
    [True, True, True, True, True, True, True, True, True]]
    

    【讨论】:

      【解决方案2】:

      这是因为星号 (*) 运算符没有创建 n 个新的独立列表。它创建了对同一个列表的 n 个引用。正如已经建议的那样,可以使用列表推导来创建包含所有独立列表的列表:

      test = [[True for i in range(cols)] for j in range(rows)]
      

      【讨论】:

        【解决方案3】:

        是的,这是一个经典的 python 陷阱。在内部乘法中,您制作了 9 个True 的副本。这会生成 相同 True 对象的 9 个实例的列表。但是,True 对象是不可变的,所以不能更改,只替换其中一个,不影响其他对象。

        相反,在外部乘法中,您创建了 相同内部列表的 9 个副本。但是,列表是可变的,因此,当您更改其中之一时,它确实会发生变化。由于外部列表由同一列表的副本组成,因此将全部更改。

        你只能通过创建 9 个不同的列表来避免它

        test = [[Test]*9 for i in range(9)]
        

        【讨论】:

          猜你喜欢
          • 2015-06-29
          • 2018-04-16
          • 2013-09-27
          相关资源
          最近更新 更多