猿问

Python - 如何检查/发现列表有引用?

python 中更令人困惑的方面之一是实例化一个列表列表(假设一个列表没有使用 numpy)——例如,如果你试图通过更简单的乘法来完成它,你最终会得到参考副本:


In [1]: a = [[0] * 4] * 4

In [2]: a

Out[2]: [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]


In [3]: a[0][1] = 1

In [4]: a

Out[4]: [[0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0]]

正如在其他各种 SO 帖子中提到的,例如this one,在没有任何引用的情况下实例化的正确方法如下:


In [5]: b = [[0 for i in range(4)] for i in range(4)]

In [6]: b         

Out[6]: [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]


In [7]: b[0][1] = 1

In [8]: b                                           

Out[8]: [[0, 1, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

问题是这样的 - 假设一个人确实像使用 list 那样定义了他们的列表a,有没有一种方法可以检查数组,以显示它正在使用引用?仅仅打印数组不会显示引用。


慕盖茨4494581
浏览 152回答 2
2回答

慕村225694

首先是一些术语:您在这里谈论的是列表(而不是数组),它总是存储对其元素的引用。检查列表中的所有引用是否都指向不同对象的一种快速方法是>>> l1 = [[0, 1], [0, 1]]>>> l2 = [[0, 1]]*2>>> >>> len(set(map(id, l1))) == len(l1) # no duplicatesTrue>>> len(set(map(id, l2))) == len(l2) # duplicatesFalse它只是检查nlength 列表中的对象是否有唯一的 id n。如果您的列表有大量元素,那么懒惰地执行此操作并返回False第一个重复的 id可能会更有效。def all_unique(lst):    seen = set()    for x in lst:        id_ = id(x)        if id_ in seen:            return False        seen.add(id_)    return True... 像这样工作:>>> all_unique(l1)True>>> all_unique(l2)False

30秒到达战场

您可以使用该id功能:>>> a = [[0] * 4] * 4>>> a[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]>>> [id(sublist) for sublist in a][1975671202696, 1975671202696, 1975671202696, 1975671202696]>>> b = [[0 for i in range(4)] for i in range(4)]>>> b[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]>>> [id(sublist) for sublist in b][1975671204808, 1975671205128, 1975671205000, 1975671204872]如您所见,在 中a,id 都是相同的,而在 中b,它们是不同的。
随时随地看视频慕课网APP

相关分类

Python
我要回答