Python Aliasing Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See http://software-carpentry.org/license.html for more information.
An alias is a second name for a piece of data 2
An alias is a second name for a piece of data Often easier (and more useful) than making a second copy 3
An alias is a second name for a piece of data Often easier (and more useful) than making a second copy If the data is immutable, aliases don't matter 4
An alias is a second name for a piece of data Often easier (and more useful) than making a second copy If the data is immutable, aliases don't matter Because the data can't change 5
An alias is a second name for a piece of data Often easier (and more useful) than making a second copy If the data is immutable, aliases don't matter Because the data can't change But if data can change, aliases can result in a lot of hard-to-find bugs 6
Aliasing happens whenever one variable's value is assigned to another variable 7
Aliasing happens whenever one variable's value is assigned to another variable first = 'isaac' variable value first 'isaac' 8
Aliasing happens whenever one variable's value is assigned to another variable first = 'isaac' second = first variable value first second 'isaac' 9
Aliasing happens whenever one variable's value is assigned to another variable first = 'isaac' second = first But as we've already seen… variable value first second 'isaac' 10
Aliasing happens whenever one variable's value is assigned to another variable first = 'isaac' second = first But as we've already seen… first = first + ' newton' variable value first second 'isaac' 'isaac newton' 11
But lists are mutable 12
But lists are mutable first = ['isaac'] variable value first 'isaac' 13
But lists are mutable first = ['isaac'] second = first variable value 14
But lists are mutable first = ['isaac'] second = first first = first.append('newton') print first ['isaac', 'newton'] variable value first second 'isaac' 'newton' 15
But lists are mutable first = ['isaac'] second = first first = first.append('newton') print first ['isaac', 'newton'] print second variable value first second 'isaac' 'newton' 16
But lists are mutable Didn't explicitly modify second first = ['isaac'] second = first first = first.append('newton') print first ['isaac', 'newton'] print second variable value first second Didn't explicitly modify second 'isaac' 'newton' 17
But lists are mutable Didn't explicitly modify second A side effect first = ['isaac'] second = first first = first.append('newton') print first ['isaac', 'newton'] print second variable value first second Didn't explicitly modify second A side effect 'isaac' 'newton' 18
Example: use lists of lists to implement a 2D grid 19
Example: use lists of lists to implement a 2D grid 3 5 7 7 5 8 6 3 2 4 2 6 5 4 3 8 20
Example: use lists of lists to implement a 2D grid 3 5 grid 7 7 5 8 6 3 2 4 2 6 5 4 3 8 21
Example: use lists of lists to implement a 2D grid 3 5 grid[0] 7 7 5 8 6 3 2 4 2 6 5 4 3 8 22
Example: use lists of lists to implement a 2D grid 3 5 grid[0][1] 7 7 5 8 6 3 2 4 2 6 5 4 3 8 23
# Correct code grid = [] for x in range(N): temp = [] for y in range(N): temp.append(1) grid.append(temp) 24
Outer "spine" of structure # Correct code grid = [] for x in range(N): temp = [] for y in range(N): temp.append(1) grid.append(temp) Outer "spine" of structure 25
Add N sub-lists to outer list # Correct code grid = [] for x in range(N): temp = [] for y in range(N): temp.append(1) grid.append(temp) Add N sub-lists to outer list 26
Create a sublist of N 1's # Correct code grid = [] for x in range(N): temp = [] for y in range(N): temp.append(1) grid.append(temp) Create a sublist of N 1's 27
# Equivalent code grid = [] for x in range(N): grid.append([]) for y in range(N): grid[-1].append(1) 28
Last element of outer list is the sublist currently being filled in # Equivalent code grid = [] for x in range(N): grid.append([]) for y in range(N): grid[-1].append(1) Last element of outer list is the sublist currently being filled in 29
# Incorrect code grid = [] EMPTY = [] for x in range(N): grid.append(EMPTY) for y in range(N): grid[-1].append(1) 30
# Incorrect code grid = [] EMPTY = [] # Equivalent code for x in range(N): grid.append(EMPTY) for y in range(N): grid[-1].append(1) # Equivalent code grid = [] for x in range(N): grid.append([]) for y in range(N): grid[-1].append(1) 31
Aren't meaningful variable names supposed to be a good thing? # Incorrect code grid = [] EMPTY = [] for x in range(N): grid.append(EMPTY) for y in range(N): grid[-1].append(1) Aren't meaningful variable names supposed to be a good thing? 32
grid = [] EMPTY = [] for x in range(N): grid.append(EMPTY) variable value grid = [] EMPTY = [] for x in range(N): grid.append(EMPTY) for y in range(N): grid[-1].append(1) x grid EMPTY 33
grid = [] EMPTY = [] for x in range(N): grid.append(EMPTY) variable value grid = [] EMPTY = [] for x in range(N): grid.append(EMPTY) for y in range(N): grid[-1].append(1) x grid EMPTY 34
grid = [] EMPTY = [] for x in range(N): grid.append(EMPTY) variable value grid = [] EMPTY = [] for x in range(N): grid.append(EMPTY) for y in range(N): grid[-1].append(1) x y grid EMPTY 35
grid = [] EMPTY = [] for x in range(N): grid.append(EMPTY) variable value grid = [] EMPTY = [] for x in range(N): grid.append(EMPTY) for y in range(N): grid[-1].append(1) x y grid EMPTY 1 36
grid = [] EMPTY = [] for x in range(N): grid.append(EMPTY) variable value grid = [] EMPTY = [] for x in range(N): grid.append(EMPTY) for y in range(N): grid[-1].append(1) x y grid EMPTY 2 1 37
grid = [] EMPTY = [] for x in range(N): grid.append(EMPTY) variable value grid = [] EMPTY = [] for x in range(N): grid.append(EMPTY) for y in range(N): grid[-1].append(1) x y grid EMPTY 1 2 1 38
You see the problem... grid = [] EMPTY = [] for x in range(N): variable value grid = [] EMPTY = [] for x in range(N): grid.append(EMPTY) for y in range(N): grid[-1].append(1) x y grid EMPTY 1 2 1 You see the problem... 39
No Aliasing first = [] second = [] 40
second = [] second = first No Aliasing Aliasing first = [] first = [] second = [] second = first 41
grid = [] for x in range(N): grid.append([]) for y in range(N): variable value grid = [] for x in range(N): grid.append([]) for y in range(N): grid[-1].append(1) x grid 42
grid = [] for x in range(N): grid.append([]) for y in range(N): variable value grid = [] for x in range(N): grid.append([]) for y in range(N): grid[-1].append(1) x grid 43
grid = [] for x in range(N): grid.append([]) for y in range(N): variable value grid = [] for x in range(N): grid.append([]) for y in range(N): grid[-1].append(1) x y grid 2 1 44
grid = [] for x in range(N): grid.append([]) for y in range(N): variable value grid = [] for x in range(N): grid.append([]) for y in range(N): grid[-1].append(1) x y grid 1 2 1 45
grid = [] for x in range(N): grid.append([]) for y in range(N): variable value grid = [] for x in range(N): grid.append([]) for y in range(N): grid[-1].append(1) x y grid 1 1 1 46
If aliasing can cause bugs, why allow it? 47
If aliasing can cause bugs, why allow it? Some languages don't 48
If aliasing can cause bugs, why allow it? Some languages don't Or at least appear not to 49
If aliasing can cause bugs, why allow it? Some languages don't Or at least appear not to Aliasing a million-element list is more efficient than copying it 50
If aliasing can cause bugs, why allow it? Some languages don't Or at least appear not to Aliasing a million-element list is more efficient than copying it Sometimes really do want to update a structure in place 51
Greg Wilson created by October 2010 Copyright © Software Carpentry 2010 This work is licensed under the Creative Commons Attribution License See http://software-carpentry.org/license.html for more information.