سؤال

To test if lst1 is a shallow copy of lst2, I did this:

def check_shallow_copy(lst1, lst2):
''' Return True if lst1 is a shallow copy of lst2.
Return False if not.
'''

for idx in range(len(lst1)):

    if lst1 == lst2 and id(lst1[idx]) == id(lst2[idx]) and lst1 is not lst2:
        return True
    else:
        return False

However, I don't think this would work if the two lists share a copy of the first element, but not any of the others. How do I change the function so that id(lst1[idx]) has to be the same as id(lst2[idx]) for all the indexes?

Also, I'm still a bit hazy between the differences of shallow and deep copies. If I wanted this function to tests if lst1 is a deep copy of lst2, what modifications should I make?

Thanks!

هل كانت مفيدة؟

المحلول 2

Let me explain a little bit what gnibbler has done.

def check_shallow_copy(lst1, lst2):
    return lst1 is not lst2 and 
           all([x is y for x, y in zip(lst1, lst2)])

The zip function takes two lists and return a list of tuples (ele1, ele2), where ele1 is from lst1 and ele2 is from lst2, preserving order.

The "is" operation returns true if two operands are the same object.

When one says A is shallow copy of B, it really means A and B shares the same set of objects as their fields. A hard copy means the fields have same value, but are different objects.

"Same object" may be quite confusing. I usually think of it as equivalence of low-level memory address. If the fields of two object have the same memory addresses, they are shallow copies of each other. However, Python makes no guarantee that "is" compares memory addresses.

For testing if it's a hard copy,

def check_hard_copy(lst1, lst2):
    return lst1 is not lst2 and 
           all([x is not y and x == y for x, y in zip(lst1, lst2)])

In this function, we are checking if x and y are different object having the same field values. Replace == to a user-defined compare function if desired.

نصائح أخرى

def check_shallow_copy(lst1, lst2):
    if lst1 is lst2 or len(lst1) != len(lst2):
        return False
    return all(x is y for x, y in zip(lst1, lst2))

It's difficult to define exactly what check_deep_copy should do. For example, if all the objects are immutable, a deep copy may look exactly like a shallow copy.

Without zip:

def check_shallow_copy(lst1, lst2):
    if lst1 is lst2 or len(lst1) != len(lst2):
        return False
    return all(lst1[i] is lst2[i] for i in range(len(lst1))) 
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top