Whilst coding a game in python I was having a problem with a portion of the code. During some debugging I ran into something really weird which I cannot explain. The first code which I show prints a certain value to the array ‘polygon’. The second code is the same but at the end I assign to the array ‘polygon’ the value printed by the first code. I would obviously expect the rest of the programme (which I do not show) to act in the same way with the first or second code because they end up giving ‘polygon’ the same value. Yet the second code makes the rest of the programme to work but the first doesn’t.
For the life of me I cannot figure out what is going on. I don’t provide the rest of the programme because I think it would be redundant as it is the same in the first and second case.
Does anyone have any idea what may be causing this? Thank you for your help.
first code:
if 1: dimensions = 3 polygon = [[[100,100],[100,-100]],[[100,-100],[-100,-100]],[[-100,-100],[-100,100]],[[-100,100],[100,100]]] for limeJuice in range(dimensions-2): p = copy.deepcopy(polygon) for j in range(len(p)): p[j][0].append(100) p[j][1].append(100) bob = copy.deepcopy(polygon) for j in range(len(bob)): bob[j][0].append(-100) bob[j][1].append(-100) q = [] for j in range(len(p)): q.append([p[j][0],bob[j][0]]) polygon = [] for pearJuice in p: polygon.append(pearJuice) for pearJuice in bob: polygon.append(pearJuice) for pearJuice in q: polygon.append(pearJuice) print(polygon) #rest of the programme #--------------------------------------------------------------------# #second code: if 1: dimensions = 3 polygon = [[[100,100],[100,-100]],[[100,-100],[-100,-100]],[[-100,-100],[-100,100]],[[-100,100],[100,100]]] for limeJuice in range(dimensions-2): p = copy.deepcopy(polygon) for j in range(len(p)): p[j][0].append(100) p[j][1].append(100) bob = copy.deepcopy(polygon) for j in range(len(bob)): bob[j][0].append(-100) bob[j][1].append(-100) q = [] for j in range(len(p)): q.append([p[j][0],bob[j][0]]) polygon = [] for pearJuice in p: polygon.append(pearJuice) for pearJuice in bob: polygon.append(pearJuice) for pearJuice in q: polygon.append(pearJuice) polygon = [[[100, 100, 100], [100, -100, 100]], [[100, -100, 100], [-100, -100, 100]], [[-100, -100, 100], [-100, 100, 100]], [[-100, 100, 100], [100, 100, 100]], [[100, 100, -100], [100, -100, -100]], [[100, -100, -100], [-100, -100, -100]], [[-100, -100, -100], [-100, 100, -100]], [[-100, 100, -100], [100, 100, -100]], [[100, 100, 100], [100, 100, -100]], [[100, -100, 100], [100, -100, -100]], [[-100, -100, 100], [-100, -100, -100]], [[-100, 100, 100], [-100, 100, -100]]] #rest of the programme
Advertisement
Answer
TLDR: The first variant has shared references between your data, the second does not.
Neither list
literals nor equality express sharing of elements with other data structures. Two objects having the same literal or being equal still allows for them to have different shared data. This makes a difference when you modify your objects:
>>> a = [[1, 2, 3], [4, 5, 6]] >>> # copy by sharing elements >>> b = [a[0], a[1]] >>> # copy by literal value >>> c = eval(repr(a)) >>> a == b == c True >>> a[1].append(7) >>> a == b # b shares data with a True >>> a == c # c shares no data False
In your case, the first polygon
shares its data with your other lists. The second polygon
created from a literal only includes new objects:
# share objects with polygon for pearJuice in p: polygon.append(pearJuice) for pearJuice in bob: polygon.append(pearJuice) for pearJuice in q: polygon.append(pearJuice) # create new objects for polygon polygon = [[[100, 100, 100], [100, -100, 100]], [[100, -100, 100], [-100, -100, 100]], [[-100, -100, 100], [-100, 100, 100]], [[-100, 100, 100], [100, 100, 100]], [[100, 100, -100], [100, -100, -100]], [[100, -100, -100], [-100, -100, -100]], [[-100, -100, -100], [-100, 100, -100]], [[-100, 100, -100], [100, 100, -100]], [[100, 100, 100], [100, 100, -100]], [[100, -100, 100], [100, -100, -100]], [[-100, -100, 100], [-100, -100, -100]], [[-100, 100, 100], [-100, 100, -100]]]
If you need to modify q
, bob
, p
and polygon
separately in your program, remember to copy.deepcopy
them.