为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕盖茨4494581 2021-09-11 10:48:00
python 中更令人困惑的方面之一是实例化一个列表列表(假设一个列表没有使用 numpy)——例如,如果你试图通过更简单的乘法来完成它,你最终会得到参考副本:In [1]: a = [[0] * 4] * 4In [2]: aOut[2]: [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]In [3]: a[0][1] = 1In [4]: aOut[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] = 1In [8]: b                                           Out[8]: [[0, 1, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]问题是这样的 - 假设一个人确实像使用 list 那样定义了他们的列表a,有没有一种方法可以检查数组,以显示它正在使用引用?仅仅打印数组不会显示引用。
查看完整描述

2 回答

?
慕村225694

TA贡献1880条经验 获得超4个赞

首先是一些术语:您在这里谈论的是列表(而不是数组),它总是存储对其元素的引用。


检查列表中的所有引用是否都指向不同对象的一种快速方法是


>>> l1 = [[0, 1], [0, 1]]

>>> l2 = [[0, 1]]*2

>>> 

>>> len(set(map(id, l1))) == len(l1) # no duplicates

True

>>> len(set(map(id, l2))) == len(l2) # duplicates

False

它只是检查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


查看完整回答
反对 回复 2021-09-11
?
30秒到达战场

TA贡献1828条经验 获得超6个赞

您可以使用该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,它们是不同的。


查看完整回答
反对 回复 2021-09-11
  • 2 回答
  • 0 关注
  • 126 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信