如何定义一组突变物?

发布于 2025-02-11 12:12:20 字数 2201 浏览 2 评论 0原文

列表是一种可变的数据类型。如果我在一个2D列表中有对同一对象有多个引用的标准列表,那么更改任何人的更改这一事实表明了一个问题:我是否能够提取有关链接的sublists的信息?

要解释,让我们考虑一个2D列表:

import random
lst = [[0] for i in range(9)]  # create list of 9 sublists with value inside
lst
[[0], [0], [0], [0], [0], [0], [0], [0], [0], [0]] .

每个指向同一对象0的sublist,但独立。如果任何给定的子徒的内容都会发生变化,则其他赞助的内容将保持稳定。所有ID都是不同的事实证明了这一点:

[id(i) for i in lst]
[139963231930640, 139963235043920, 139963236442592, 139963222312992, 139963783242688, 139963234936784, 139963233636256, 139963233634176, 139963233635056] .

现在让我们创建一个随机的对象示例:

indcs = random.sample(range(9), 9)    

然后使用以下功能修改标准符:

def mutables(a):
    for i in range(len(a) - 1):
        lst[a[i+1]] = lst[a[i]]
        lst[a[i]][0] += 1

mutables(indcs[:3])
mutables(indcs[3:6])
mutables(indcs[6:])

lst
[[2], [2], [2], [2], [2], [2], [2], [2], [2]] .

现在列表包含3个组3个sublists,一个组的每个元素指向同一对象。 lst中只有3IDSX3:

[id(i) for i in lst]
[139963231930640, 139963235043920, 139963236442592, 139963235043920, 139963236442592, 139963231930640, 139963235043920, 139963231930640, 139963236442592] .

如果我们更改,例如列表的第三个元素,它会更改组的每个元素:

lst[2][0] += 1
lst
[[2], [2], [3], [2], [3], [2], [2], [2], [3]] .

在此,Sublists(2,4,8)会更改。第二个(0,5,7)和第三(1,3,6)组的行为方式相同:

lst[0][0] += 1
lst
[[3], [2], [3], [2], [3], [3], [2], [3], [3]]
lst[1][0] += 1
lst
[[3], [3], [3], [3], [3], [3], [3], [3], [3]] .

Sublists内部整数值的更改没有更改IDS:

[id(i) for i in lst]
    [139963231930640, 139963235043920, 139963236442592, 139963235043920, 139963236442592, 139963231930640, 139963235043920, 139963231930640, 139963236442592],

而是每次添加1新组成员到达提供了有关组大小的有用信息。

我的问题的症结在于,虽然保留了订订式链接的信息,但如何提取每个组的索引((2,4,8),(0,5,7),(1,3,6) )无需参考indcs及其最初如何分组:[:3:6:]?我可以更改第一个冠军值,跟踪他人的变化并弹出循环,但是该信息应隐含地可用,以组中的一个元素突变为基础。有什么方法可以收集它吗?例如,我可以获得sublist的id(name),并尝试通过此处描述,但是这些选项返回值,而不是其名称。

Lists are a mutable data type. If I have sublists inside a 2d list that have multiple references to the same object, the fact that changing any one makes changes in others suggests a question: am I able to extract information about linked sublists?

To explain, let's consider a 2d list:

import random
lst = [[0] for i in range(9)]  # create list of 9 sublists with value inside
lst
[[0], [0], [0], [0], [0], [0], [0], [0], [0], [0]] .

Each sublist pointing to the same object 0, but independently. If any given sublist's contents change, the other sublists contents will remain stable. The fact that all IDs are different proves this point:

[id(i) for i in lst]
[139963231930640, 139963235043920, 139963236442592, 139963222312992, 139963783242688, 139963234936784, 139963233636256, 139963233634176, 139963233635056] .

Now let's create a random sample of objects:

indcs = random.sample(range(9), 9)    

and then modify the sublists using the following function:

def mutables(a):
    for i in range(len(a) - 1):
        lst[a[i+1]] = lst[a[i]]
        lst[a[i]][0] += 1

mutables(indcs[:3])
mutables(indcs[3:6])
mutables(indcs[6:])

lst
[[2], [2], [2], [2], [2], [2], [2], [2], [2]] .

The list now contains 3 groups of 3 sublists, each element of a group pointing to the same object. There are only 3IDsx3 in lst:

[id(i) for i in lst]
[139963231930640, 139963235043920, 139963236442592, 139963235043920, 139963236442592, 139963231930640, 139963235043920, 139963231930640, 139963236442592] .

If we change, e.g., the third element of a list, it changes each element of a group:

lst[2][0] += 1
lst
[[2], [2], [3], [2], [3], [2], [2], [2], [3]] .

Here, the sublists (2,4,8) are changed. The 2nd(0,5,7) and 3rd(1,3,6) groups behave the same way:

lst[0][0] += 1
lst
[[3], [2], [3], [2], [3], [3], [2], [3], [3]]
lst[1][0] += 1
lst
[[3], [3], [3], [3], [3], [3], [3], [3], [3]] .

The change of an integer values inside sublists did not change IDs:

[id(i) for i in lst]
    [139963231930640, 139963235043920, 139963236442592, 139963235043920, 139963236442592, 139963231930640, 139963235043920, 139963231930640, 139963236442592],

but adding 1 every time a new group member arrives provides useful information on the group size.

The crux of my question is, while the information about link between the sublists is retained, how to extract the indices of each group ((2,4,8),(0,5,7),(1,3,6)) without needing to refer to indcs and how it was originally grouped: [:3:6:]? I could change the 1st sublist value, track changes in others and pop them in a loop, but this information should be implicitly available on the basis of which an element in a group mutates. Is there any way to collect it? E.g., I can get id(name) of a sublist and try to find linked sublists by one of the methods in described here or here, but these options return values, not their names.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

眉目亦如画i 2025-02-18 12:12:20

我认为您对正在处理的列表的列表的可变形性有些困惑。

>>> class Obj:
...   name: str = None
...   def __init__(self, name):
...     self.name = name
...
>>> o = Obj("Athena")
>>> o.name
'Athena'
>>> a = Obj("Athena")
>>> b = Obj("Bacchus")
>>> c = Obj("Clotho")
>>>
>>> la = [a, b]
>>> lb = [a, b]
>>> ls = [la, lb]
>>> for sublist in ls:
...   for item in sublist:
...     print(f"{item.name}")
...
Athena
Bacchus
Athena
Bacchus
>>> ls[0][0] = c
>>> for sublist in ls:
...   for item in sublist:
...     print(f"{item.name}")
...
Clotho
Bacchus
Athena
Bacchus

这表明,如果您单独创建订书片,即使是该列表的元素相同的对象,订书片是单独的可变对象,并且更改一个对象并不意味着更改其他对象。

相反,请考虑:

>>> la = [a, b]
>>> ls = [la, la]
>>> for sublist in ls:
...   for item in sublist:
...     print(f"{item.name}")
...
Athena
Bacchus
Athena
Bacchus
>>> ls[0][0] = c
>>> for sublist in ls:
...   for item in sublist:
...     print(f"{item.name}")
...
Clotho
Bacchus
Clotho
Bacchus

在这里我们看到,如果我们使用相同的sublist,la,当我们更改一个sublist时,我们会更改另一个sublist。要进一步迈出一步:

>>> lb = [a, c]
>>> ls[1] = lb
>>> for sublist in ls:
...   for item in sublist:
...     print(f"{item.name}")
...
Athena
Bacchus
Athena
Clotho
>>> ls[0][0] = d
>>> for sublist in ls:
...   for item in sublist:
...     print(f"{item.name}")
...
Demosthenes
Bacchus
Athena
Clotho

在这里,我们将外部列表的第二个要素指向了一个新列表。现在,当我们更改第一个sublist的元素时,它不会更改第二个sublist。这是有道理的,因为这些是不同的列表。

这里的结果是,列表的每个元素都指向一个对象。多个元素可以指向同一对象。因此,对于您的外部列表,您可以将多个元素指向同一对象,一个sublist,并且对于任何此类sublist更改,在外部列表的任何其他元素中都可以看到指向同一sublist对象的任何其他元素。但是只有这种情况。

这就是您在问题中的推理并不是很有意义的:

>>> lb = [a, b]
>>> ls = [la, lb, la]
>>> for sublistA in ls:
...   for sublistB in ls:
...     print("Equal") if sublistA is sublistB else print("Not equal")
...
Equal
Not equal
Equal
Not equal
Equal
Not equal
Equal
Not equal
Equal

在这里我们看到,尽管lalb是等效的,但它们不是同一对象。实际上,您在复杂的示例中所做的一切都是在将 sublist对象添加到外部列表的地方。类似于:

>>> ls = [la, lb, lb, la]
>>> ls[0][0] = c
>>> for sublist in ls:
...   for item in sublist:
...      print(f"{item.name}")
...
Clotho
Bacchus
Athena
Bacchus
Athena
Bacchus
Clotho
Bacchus

这与您放入的“组”无关,只是外部列表中的每个元素都在引用特定的列表对象。这就是“隐式跟踪”发生的地方,您可以像我一样使用比较来获取该信息。因为列表不可伸缩,所以在不为列表中创建包装器的情况下,很难进行反向查找字典,并且每次进行对象比较(而不是IS is 和== 在比较两个对象时,尤其是列表!)。除了这两个选项之外 - 保留一个单独的变量,可以跟踪每个唯一对象的索引(在这种情况下,每个具有多个元素的sublist)试图避免。

I think you have some confusion about where the mutability of lists that you're dealing with lays.

>>> class Obj:
...   name: str = None
...   def __init__(self, name):
...     self.name = name
...
>>> o = Obj("Athena")
>>> o.name
'Athena'
>>> a = Obj("Athena")
>>> b = Obj("Bacchus")
>>> c = Obj("Clotho")
>>>
>>> la = [a, b]
>>> lb = [a, b]
>>> ls = [la, lb]
>>> for sublist in ls:
...   for item in sublist:
...     print(f"{item.name}")
...
Athena
Bacchus
Athena
Bacchus
>>> ls[0][0] = c
>>> for sublist in ls:
...   for item in sublist:
...     print(f"{item.name}")
...
Clotho
Bacchus
Athena
Bacchus

This demonstrates that if you create the sublists individually, even if the objects that are the elements of that list are the same, the sublists are separate mutable objects, and changing one does not mean changing the others.

Consider, instead:

>>> la = [a, b]
>>> ls = [la, la]
>>> for sublist in ls:
...   for item in sublist:
...     print(f"{item.name}")
...
Athena
Bacchus
Athena
Bacchus
>>> ls[0][0] = c
>>> for sublist in ls:
...   for item in sublist:
...     print(f"{item.name}")
...
Clotho
Bacchus
Clotho
Bacchus

Here we see that if we use the same sublist, la, when we change one sublist we change another sublist. To take this a step further:

>>> lb = [a, c]
>>> ls[1] = lb
>>> for sublist in ls:
...   for item in sublist:
...     print(f"{item.name}")
...
Athena
Bacchus
Athena
Clotho
>>> ls[0][0] = d
>>> for sublist in ls:
...   for item in sublist:
...     print(f"{item.name}")
...
Demosthenes
Bacchus
Athena
Clotho

Here, we've pointed the second element of the outer list to a new list. Now when we change an element of the first sublist, it does not change the second sublist. This makes sense, because these are different lists.

The upshot here is that each element of a list points to a single object. Multiple elements can point to the same object. So, for your outer list, you can have multiple elements point to the same object, a sublist, and for any such sublist changes to that sublist will be visible in any other element of the outer list that points to the same sublist object. But only so long as that is the case.

And this is where your reasoning in your question doesn't quite make sense:

>>> lb = [a, b]
>>> ls = [la, lb, la]
>>> for sublistA in ls:
...   for sublistB in ls:
...     print("Equal") if sublistA is sublistB else print("Not equal")
...
Equal
Not equal
Equal
Not equal
Equal
Not equal
Equal
Not equal
Equal

Here we see that although la and lb are equivalent, they are not the same object. And really, all you're doing in your complicated example is shuffling around where you add the sublist object to your outer list. Something akin to:

>>> ls = [la, lb, lb, la]
>>> ls[0][0] = c
>>> for sublist in ls:
...   for item in sublist:
...      print(f"{item.name}")
...
Clotho
Bacchus
Athena
Bacchus
Athena
Bacchus
Clotho
Bacchus

This has nothing to do with the 'groups' you're putting them in, it's just that each element in the outer list is referencing a particular list object. That is where the 'implicit tracking' is occurring, and you can get at that information by using a comparison as I did. Because a list is not hashable, it's difficult to do a reverse lookup dictionary without creating a wrapper for the list, and it's expensive to do the object comparison every time (and not the difference between is and == in comparing two objects, especially lists!). Apart from those two options - keeping a separate variable that tracks the indices of each unique object (in this case, each sublist that has itself multiple elements) - there isn't a lot you can do that would be avoiding the work you're trying to avoid.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文