2016-02-01 7 views
0

Предположим, я хочу создать вложенный список с последовательностью чисел и не хочу повторять последовательность повторений.Python Создание вложенного списка со случайным модулем

т.е. я хотел бы что-то вроде этого: [[1,2,3,4],[2,1,3,4],[4,2,3,1]], где len списка зависит от того, сколько не повторяющаяся последовательности числа, которое я мог бы генерировать в ограниченной попытке (четыре попытки в ниже случае)

Так вот мою первую попытку:

import random 
rng = random.Random() 
bd =list(range(4)) 
i = 0 
result =[] 

while i <4: 
    rng.shuffle(bd) 
    if bd not in result: 
     result.append(bd) 
    i +=1 
print(result) 

Я создал список bd = [0,1,2,3] прежде, чем ввести цикл while.

При запуске вышеуказанного кода я неожиданно получаю только один элемент в своем вложенном списке.

Результат: [[1, 2, 0, 3]]

Но если я изменить код немного, он работает, как я ожидал. Вот мой модифицированный код:

import random 
rng = random.Random() 
i = 0 
result =[] 

while i <4: 
    bd =list(range(4)) 
    rng.shuffle(bd) 
    if bd not in result: 
     result.append(bd) 
    i +=1 
print(result) 

Результат: [[3, 2, 0, 1], [1, 0, 3, 2], [0, 1, 3, 2]]

Что я могу сделать, это просто сбросить список bd в каждом цикле снова.

По моему мнению, список bd будет перетасован в каждом цикле, поэтому сброс bd на [0,1,2,3] должен быть бессмысленным. Может ли кто-нибудь объяснить мне, почему работает модифицированный код? Благодарю.

+0

Также см http://stackoverflow.com/questions/240178/python-list-of-lists-changes-reflected-across-sublists-unexpectedly –

ответ

2

Списки и подобные объекты в Python, называются по ссылке. Рассмотрим следующий простой пример:

a_list = [1,2,3,4,5] 
another_list = [] 

for i in range(5): 
    another_list.append(a_list) 
    a_list[0] = i + 10 

print(another_list) 

Вы ожидали бы выход быть:

[[10, 2, 3, 4, 5], [11, 2, 3, 4, 5], [12, 2, 3, 4, 5], [13, 2, 3, 4, 5], [14, 2, 3, 4, 5]] 

Однако выход вы видите:

[[14, 2, 3, 4, 5], [14, 2, 3, 4, 5], [14, 2, 3, 4, 5], [14, 2, 3, 4, 5], [14, 2, 3, 4, 5]] 

Каждый раз, когда вы звоните another_list.append(a_list), вы append ссылка на a_list. Затем вы меняете a_list, а ранее добавленные ссылки указывают на измененный список.

В конце a_list равен [14, 2, 3, 4, 5], а another_list содержит пять идентичных ссылок на этот список.


Назад к вашему делу. Чтобы предотвратить это происходит с вами, вы можете создать копию списка каждый раз, когда вы добавляете его, as documented here:

import random 
rng = random.Random() 
i = 0 
result =[] 

while i <4: 
    bd =list(range(4)) 
    rng.shuffle(bd) 
    if bd not in result: 
     # Use [:] to create a slice of bd which actually contains the whole list 
     result.append(bd[:]) 
    i +=1 
print(result) 
+0

Спасибо Archimaredes. Теперь все имеет смысл. – Le0

1

С вашей первой попытки вы перетасовываете и добавляете список, чтобы получить результат каждый раз. Попробуйте использовать копию, взяв фрагмент всего списка: bd[:] - полностью независимый объект, который не будет изменен, когда вы перетасовываете оригинал bd в следующий раз по кругу.

import random 
rng = random.Random() 
bd =list(range(4)) 
i = 0 
result =[] 

while i <4: 
    rng.shuffle(bd) 
    if bd not in result: 
     result.append(bd[:]) 
    i +=1 
print(result) 

Выход:

[[2, 1, 3, 0], [1, 2, 3, 0], [0, 3, 2, 1]] 
+0

Спасибо xnx :) Это работает и решает мою проблему. – Le0

1

Это случилось потому, что вы добавляете bd к result и в следующей итерации вы используете bd, они имеют та же ссылка.
Во втором вы создаете новый список (разные ссылки) на каждой итерации.

+0

Спасибо WoLy :) чистый и понятный ответ, который решает мою проблему – Le0

1

Есть одна небольшая проблема с вашим кодом: shuffle выполняет изменение на месте, поэтому он изменяет объект, на который ссылается ваша переменная. Запустив первый код, вы всегда получите один результат - последнюю операцию перетасовки. Чтобы этого избежать, необходимо приложить копию списка:

import random 
rng = random.Random() 
bd =list(range(4)) 
i = 0 
result =[] 

while i <4: 
    rng.shuffle(bd) 
    if bd not in result: 
     result.append(bd[:]) 
    i +=1 
print(result)