lundi 20 août 2018

Python redefining entire list of lists of random numbers upon completion of iteration through a for-loop

I've worked with Python for a few years now and do not know why it's behaving in the following manner. But that said, I don't think I've ever attempted to work with random numbers in this particular way. Please feel free to check if your python (I use 3.5) is acting the same way.

Target: I want to produce a list of lists where each nested list contains the same values but in different order.

What code I have:

import random

# Define number slots
opts = [1,2,3,4,5]
li = []

for x in range(len(opts)):
    random.shuffle(opts)    # Jumbles the options list
    li.append(opts)     # Append that list to the parent list

So, I declare a list of options containing the values that I want. Then I use random.shuffle() to mix-up the list. It is then appended to the master list. But when I go to inspect the results, each nested list has the same ordered list of numbers...

>>> for each in li:
    print(each)

[5, 4, 2, 1, 3]
[5, 4, 2, 1, 3]
[5, 4, 2, 1, 3]
[5, 4, 2, 1, 3]
[5, 4, 2, 1, 3]
>>>

I originally had code more complex than above, but Because I hadn't worked with pseudo-random numbers in python extensively before, I thought I didn't fully understand the random method. So I kept making the code simpler and simpler. But the outcome was the same. So I finally figured out that the for loop worked as intended until it finished iterating...

Code with guided comments:

import random

# Define number slots
opts = [1,2,3,4,5]
li = []

print("Now defining the list: \n")
for x in range(len(opts)):
    random.shuffle(opts)    # Jumble the options list
    li.append(opts)     # Append that list
    print("li[{}] = {}".format(x,li[x]))    # Outputs list associated with index

print("\nNow print each index:")
for y in range(len(li)):
    print("li[{}] = {}".format(y,li[y]))

Results:

Now defining the list:
li[0] = [3, 4, 2, 5, 1]
li[1] = [2, 1, 5, 3, 4]
li[2] = [1, 5, 2, 3, 4]
li[3] = [5, 1, 2, 4, 3]
li[4] = [2, 1, 5, 3, 4]

Now print each index:
li[0] = [2, 1, 5, 3, 4]
li[1] = [2, 1, 5, 3, 4]
li[2] = [2, 1, 5, 3, 4]
li[3] = [2, 1, 5, 3, 4]
li[4] = [2, 1, 5, 3, 4]

So, the first output section reflects each appended nested list. The second block of output reflects the same, but after the for-loop completes its iteration.

I'm at a loss why it's behaving this way. For some reason, each nested list is changed to the last appended list but must happen upon or after completion of the for-loop.

Any ideas why?




Aucun commentaire:

Enregistrer un commentaire