嵌套列表索引 [英] Nested List Indices

查看:73
本文介绍了嵌套列表索引的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在下面显示的代码中使用 Python 中的嵌套列表时遇到了一些问题.

基本上,我有一个包含所有 0 值的 2D 列表,我想在循环中更新列表值.

然而,Python 不会产生我想要的结果.我对 range() 和 Python 列表索引有什么误解吗?

some_list = 4 * [(4 * [0])]对于范围内的 i (3):对于范围内的 j(3):some_list[i+1][j+1] = 1对于范围内的 i (4):打印(some_list[i])

我预期的结果是:

[0, 0, 0, 0][0, 1, 1, 1][0, 1, 1, 1][0, 1, 1, 1]

但 Python 的实际结果是:

[0, 1, 1, 1][0, 1, 1, 1][0, 1, 1, 1][0, 1, 1, 1]

这是怎么回事?

解决方案

问题是由于python选择通过引用传递列表.

通常变量是按值"传递的,因此它们独立运行:

<预><代码>>>>一 = 1>>>b = a>>>一 = 2>>>打印 b1

但是由于列表可能会变得非常大,而不是围绕内存移动整个列表,Python 选择只使用引用(C 术语中的指针").如果将一个变量分配给另一个变量,则只分配对它的引用.这意味着你可以有两个变量指向内存中的同一个列表:

<预><代码>>>>a = [1]>>>b = a>>>[0] = 2>>>打印 b[2]

因此,在您的第一行代码中,您有 4 * [0].现在 [0] 是一个指向内存中值 0 的指针,当你乘以它时,你会得到四个指向内存中相同位置的指针.但是当您更改其中一个值时,Python 知道指针需要更改以指向新值:

<预><代码>>>>a = 4 * [0]>>>一种[0, 0, 0, 0]>>>[id(v) for v in a][33302480、33302480、33302480、33302480]>>>[0] = 1>>>一种[1, 0, 0, 0]

当你将这个列表相乘时问题就来了——你得到了列表指针的四个副本.现在,当您更改一个列表中的其中一个值时,所有四个值都会一起更改:

<预><代码>>>>[0][0] = 1>>>一种[[1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0]]

解决方案是避免第二次乘法.循环完成这项工作:

<预><代码>>>>some_list = [(4 * [0]) for _ in range(4)]

I have experienced some problem by using a nested list in Python in the code shown bleow.

Basically, I have a 2D list contains all 0 values, I want to update the list value in a loop.

However, Python does not produce the result I want. Is there something that I misunderstand about range() and Python list indices?

some_list = 4 * [(4 * [0])]
for i in range(3):
    for j in range(3):
        some_list[i+1][j+1] = 1
for i in range(4):
    print(some_list[i])

The results I expected are:

[0, 0, 0, 0]
[0, 1, 1, 1]
[0, 1, 1, 1]
[0, 1, 1, 1]

But the actual results from Python are:

[0, 1, 1, 1]
[0, 1, 1, 1]
[0, 1, 1, 1]
[0, 1, 1, 1]

What's going on here?

解决方案

The problem is caused by the fact that python chooses to pass lists around by reference.

Normally variables are passed "by value", so they operate independently:

>>> a = 1
>>> b = a
>>> a = 2
>>> print b
1

But since lists might get pretty large, rather than shifting the whole list around memory, Python chooses to just use a reference ('pointer' in C terms). If you assign one to another variable, you assign just the reference to it. This means that you can have two variables pointing to the same list in memory:

>>> a = [1]
>>> b = a
>>> a[0] = 2
>>> print b
[2]

So, in your first line of code you have 4 * [0]. Now [0] is a pointer to the value 0 in memory, and when you multiply it, you get four pointers to the same place in memory. BUT when you change one of the values then Python knows that the pointer needs to change to point to the new value:

>>> a = 4 * [0]
>>> a
[0, 0, 0, 0]
>>> [id(v) for v in a]
[33302480, 33302480, 33302480, 33302480]
>>> a[0] = 1
>>> a
[1, 0, 0, 0]

The problem comes when you multiply this list - you get four copies of the list pointer. Now when you change one of the values in one list, all four change together:

>>> a[0][0] = 1
>>> a
[[1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0]]

The solution is to avoid the second multiplication. A loop does the job:

>>> some_list = [(4 * [0]) for _ in range(4)]

这篇关于嵌套列表索引的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆