2

I am trying to create a python program to shuffle an array so that the horizontal and vertical rows never have a repeat number.

Input: [1,2,3,4]

Output: 
1 2 3 4
2 3 4 1
3 4 1 2
4 1 2 3

My program calculates the shifting of each element correctly, but when it appends the list to the output list, the output list only has repeat copies of the last item in the list.

def numbers(list_of_numbers): 
    finalValues = [list_of_numbers]
    #print(list_of_numbers)
    for i in range(1,len(list_of_numbers)):
        print("Last array of final: ", finalValues[-1])
        tempArray = finalValues[-1]
        print("Temp Array: ",tempArray) 
        temp = tempArray[0]
        for j in range(0,len(list_of_numbers)-1):
            tempArray[j] = tempArray[j+1]
        tempArray[-1] = temp 
        finalValues.append(tempArray)

        print("Final Values: ",finalValues)
    return finalValues
numbers([1,2,3,4])

Program Output

[[4, 1, 2, 3], [4, 1, 2, 3], [4, 1, 2, 3], [4, 1, 2, 3]]

Correct Output

[[1,2,3,4], [2,3,4,1], [3,4,1,2], [4,1,2,3]]
Krish
  • 415
  • 2
  • 11
  • you are wrapping your input list in a new list then taking the last element of the new list whcih is the entire iput list. which you then keep editing the same list – Chris Doyle Dec 21 '19 at 19:29

3 Answers3

3

The problem comes from the line:

tempArray = finalValues[-1]

You don't create a copy of the previous list, but only a new name to refer to it. After that, all changes you make to tempArray are actually changes to this list, and when you finally do:

finalValues.append(tempArray)

you just add another reference to this same list in finalValues.

In the end, finalValues contains 4 references to the same list, which you can access with finalValues[0], finalValues[1]...

What you need is to create a new list by copying the previous one. One way to do it is to use a slice:

tempArray = finalValues[-1][:]

You can find other ways to close or copy a list in this question

And so, the complete code gives the expected output:

Last array of final:  [1, 2, 3, 4]
Temp Array:  [1, 2, 3, 4]
Final Values:  [[1, 2, 3, 4], [2, 3, 4, 1]]
Last array of final:  [2, 3, 4, 1]
Temp Array:  [2, 3, 4, 1]
Final Values:  [[1, 2, 3, 4], [2, 3, 4, 1], [3, 4, 1, 2]]
Last array of final:  [3, 4, 1, 2]
Temp Array:  [3, 4, 1, 2]
Final Values:  [[1, 2, 3, 4], [2, 3, 4, 1], [3, 4, 1, 2], [4, 1, 2, 3]]

[[1, 2, 3, 4], [2, 3, 4, 1], [3, 4, 1, 2], [4, 1, 2, 3]]
Thierry Lathuille
  • 23,663
  • 10
  • 44
  • 50
1

Thierry has provided a very comprehensive explanation of why your code doesn't work as you expect. As such it is the best answer to your question.I have added my answer just as an example of you you can code this in a less complex way .

create the 2d list with the first index as list of numbers. for each iteration take the last index of temp and slice from index 1 to the end then add on index 0.

then return the list

def numbers(list_of_numbers):
    temp = [list_of_numbers]
    for _ in range(1, len(list_of_numbers)):
        temp.append(temp[-1][1:] + temp[-1][0:1])
    return temp
print(numbers([1,2,3,4]))

OUTPUT

[[1, 2, 3, 4], [2, 3, 4, 1], [3, 4, 1, 2], [4, 1, 2, 3]]
Chris Doyle
  • 10,703
  • 2
  • 23
  • 42
0

The problems is in shallow assignment of arrays. You should make deep copy, to really clone arrays, to make them independent.

I did it in your own code. There are a few changes of your code:

  1. import copy that it have been added to first row.
  2. Three usages of copy.deepcopy function instead of =(simple assignment).

    import copy

    def numbers(list_of_numbers):
        finalValues = copy.deepcopy([list_of_numbers])
        #print(list_of_numbers)
        for i in range(1,len(list_of_numbers)):
            print("Last array of final: ", finalValues[-1])
            tempArray = copy.deepcopy(finalValues[-1])
            print("Temp Array: ",tempArray)
            temp = tempArray[0]
            for j in range(0,len(list_of_numbers)-1):
                tempArray[j] = tempArray[j+1]
            tempArray[-1] = temp
            finalValues.append(copy.deepcopy(tempArray))

            print("Final Values: ",finalValues)
        return finalValues

    numbers([1,2,3,4])

Program Output

[[4, 1, 2, 3], [4, 1, 2, 3], [4, 1, 2, 3], [4, 1, 2, 3]]

Program Output

[[1,2,3,4], [2,3,4,1], [3,4,1,2], [4,1,2,3]]
Seyfi
  • 1,832
  • 1
  • 20
  • 35