简体   繁体   English

Python 中是否有语句仅当两个复合列表的所有项目具有不同的 id 时才会解析为 True

[英]Is there a statement in Python that will resolve as True only if all items of two compound lists have different id's

I recently found out that certain assignments, eg,我最近发现某些作业,例如,

list2 = list1*1  
list2 = list1[:]  
list2 = copy.copy(list1)  (need to import copy)  

when used on compound lists (for example lists of lists) produce list2 that has different id from list1 but with components that have the same id's.当在复合列表(例如列表列表)上使用时,会生成具有与 list1 不同 id 但具有相同 id 的组件的 list2。 Thus a subsequent change in a component of list2 will also change the corresponding component of list1.因此,list2 的某个组件的后续更改也将更改 list1 的相应组件。 The list2 is list1 statement will resolve as False whether or not some lists components have the same id.无论某些列表组件是否具有相同的 id, list2 is list1语句都将解析为False

My question:我的问题:
Is there something like a notTheSame command that resolves True only if list1 and list2 as well as all their components have different ids?只有当 list1 和 list2 以及它们的所有组件都具有不同的 id 时,是否有类似notTheSame命令才能解析True东西?

No, you would have to write a function to compare all items by their IDs, but note it only matters if they are "not the same" if the items are mutable, and their is no "ismutable()" function.不,您必须编写一个函数来通过它们的 ID 比较所有项目,但请注意,如果这些项目是可变的,那么只有当它们“不相同”时才重要,并且它们不是“ismutable()”函数。

If you want your list copies to also copy sub-lists and other mutable items, use:如果您希望您的列表副本也复制子列表和其他可变项目,请使用:

import copy
list1 = copy.deepcopy(list2)

Note that your hypothetical notTheSame function wouldn't work even with deepcopy, because immutable items do not need to have unique IDs.请注意,即使使用 deepcopy,您假设的notTheSame函数也不起作用,因为不可变项不需要具有唯一 ID。 Python is free to optimize immutable items by re-using the object, since it can't be changed. Python 可以通过重用对象来自由优化不可变项,因为它无法更改。

Here's an example:下面是一个例子:

import copy

list1 = [1,2,[3,4,5],6,7,[8,9,10]]

list2 = list1.copy()
list3 = copy.deepcopy(list1)

def ids(x):
    return ' '.join([f'{id(i):08x}' for i in x])

print(ids(list1))
print(ids(list2))
print(ids(list3))

Output:输出:

7ffdff4006a0 7ffdff4006c0 22da8898200 7ffdff400740 7ffdff400760 22da8898a00
7ffdff4006a0 7ffdff4006c0 22da8898200 7ffdff400740 7ffdff400760 22da8898a00
7ffdff4006a0 7ffdff4006c0 22da88aea80 7ffdff400740 7ffdff400760 22da88ae980

Note that the shallow copy (2nd line) IDs are all the same.请注意,浅拷贝(第 2 行)ID 都是相同的。 Only the 3rd and 6th item have a new ID in list3 (3rd line).只有第 3 项和第 6 项在list3 (第 3 行)中有新 ID。 The integer objects (in CPython's implementation anyway) don't change their IDs.整数对象(无论如何在 CPython 的实现中)不会改变它们的 ID。 Only the mutable list objects change.只有可变列表对象发生变化。

A simple function can be written up to manually do a check:可以编写一个简单的函数来手动进行检查:

def all_unique(list1, list2):
    return id(list1) != id(list2) and all(id(x) != id(y) for x, y in zip(list1, list2))

There is no built-in that I know of for this explicit purpose.我所知道的没有内置的用于这个明确的目的。

This seems like an odd requirement though.不过,这似乎是一个奇怪的要求。 Just to clear up "certain assignments" returning elements with the same IDs: all the methods you show (sequence multiplication, slicing, and copy.copy ) all produce shallow copies.只是为了清除返回具有相同 ID 的元素的“某些分配”:您显示的所有方法(序列乘法、切片和copy.copy )都产生拷贝。 All they do is copy the outer structure, while copying references to the underlying objects into the new structure.它们所做的只是复制外部结构,同时将底层对象的引用复制到新结构中。 If you want to ensure that all objects in the copy are unique (or at least unique in the cases that matter), use copy.deepcopy instead.如果您想确保副本中的所有对象都是唯一的(或者至少在重要的情况下是唯一的),请改用copy.deepcopy It will recursively go through supporting structures and copy all objects.它将递归地遍历支持结构并复制所有对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM