2

I'm trying to take a 3 digit number then generate children in the following order: a. 1 is subtracted from the first digit b. 1 is added to the first digit c. 1 is subtracted from the second digit d. 1 is added to the second digit e. 1 is subtracted from the third digit f.1 is added to the third digit

Don't subtract if 0 and don't add if 9.

Here's the code I'm using to do it where p is an array of 3 digits

def generate_children(p):
    children = []
    i=0
    for x in p:
        if x != 0:
            child1 = p
            child1[i] = child1[i]-1
            children.append(child1)
            print(children)
        if x != 9:
            child2 = p
            child2[i] = child2[i] + 1
            children.append(child2)
            print(children)
        i+=1
    return children

If I give this a parent of 345 it should return [245,445,335,355,344,346] at the end. However when I run it with the print statements it gives me below. Why does every entry in the array become the same after being appended?

[[2, 4, 5]]

[[3, 4, 5], [3, 4, 5]]

[[3, 3, 5], [3, 3, 5], [3, 3, 5]]

[[3, 4, 5], [3, 4, 5], [3, 4, 5], [3, 4, 5]]

[[3, 4, 4], [3, 4, 4], [3, 4, 4], [3, 4, 4], [3, 4, 4]]

[[3, 4, 5], [3, 4, 5], [3, 4, 5], [3, 4, 5], [3, 4, 5], [3, 4, 5]]

augurar
  • 12,081
  • 6
  • 50
  • 65
Dennis Liu
  • 43
  • 5
  • What is the data type of `p`? It would be better if you would provide the code to call this function. – trincot Apr 20 '21 at 09:08
  • 1
    Does this answer your question? [List of lists changes reflected across sublists unexpectedly](https://stackoverflow.com/questions/240178/list-of-lists-changes-reflected-across-sublists-unexpectedly) – Manuel Apr 20 '21 at 09:11
  • 1
    @Manuel I don't think that will help the OP, as in that case it's a subtlety of how the `*` operation works for lists, whereas in this case it has to do with confusion about variables/references vs values. – augurar Apr 20 '21 at 09:13
  • @augurar I see it as the same issue, just created differently, and I think understanding the issue as explained for that other case (i.e., that all sublists are the same list object) will also make them understand this one. – Manuel Apr 20 '21 at 11:20

1 Answers1

3

Use list.copy()

def generate_children(p):
    children = []
    i = 0
    for x in p:
        if x != 0:
            child1 = p.copy()
            child1[i] = child1[i] - 1
            children.append(child1)
            print(children)
        if x != 9:
            child2 = p.copy()
            child2[i] = child2[i] + 1
            children.append(child2)
            print(children)
        i += 1
    return children

In python, if you bind a name to a list, it doesn't copy the list, it point to the same memory slot.

a = [1, 2, 3]
# a -----> [1, 2, 3]

b = a
# a -----> [1, 2, 3]
#          ^
#          |
# b --------

a[1] = 4
# a -----> [1, 4, 3]
#          ^
#          |
# b --------
print(b)  # [1, 4, 3]

if you use list.copy():

a = [1, 2, 3]
# a -----> [1, 2, 3]

b = a.copy()
# a -----> [1, 2, 3]
# b -----> [1, 2, 3]

a[1] = 4
# a -----> [1, 4, 3]
# b -----> [1, 2, 3]

print(b)  # [1, 2, 3]

You code:

You can visualize the behavior of your code here: generate_children behavior

original code

Fixed code:

You can visualize the behavior of the fixed code here: fixed_generate_children behavior

fixed code

Dorian Turba
  • 3,260
  • 3
  • 23
  • 67