Добавление списков в глобальный список в python

Я пытаюсь создать список перестановок (также списков), добавляя глобальный список по мере создания каждой перестановки. Я могу сказать, что перестановки генерируются правильно, печатая каждую после ее создания. Однако после вызова функции мой глобальный список содержит только исходный список для каждого случая, когда функция генерировала перестановку.

    array = []

    def perms(a, k):
        if (k == len(a)):
            global array
            array.append(a)
            print(a) #perms function is working properly
        else:
             for i in range(k, len(a)):
                     a[k], a[i] = a[i], a[k]
                     perms(a, k+1)
                     a[k], a[i] = a[i], a[k]


    perms([1,2,3,4], 0)

    #only prints the original list for each time a perm was generated
    for i in array: print(i)

Когда я печатаю внизу, он показывает массив = [[1,2,3,4], [1,2,3,4], ...]

Похоже, что мой глобальный массив списка может видеть только параметр perms a в той области, в которой он был вызван.

Как бы это правильно сделать?


person user2806070    schedule 06.06.2014    source источник
comment
Вы изменяете один и тот же список снова и снова, поэтому ваши последующие изменения отменяют предыдущие. Есть ли причина, по которой вы не используете itertools.permutations?   -  person BrenBarn    schedule 06.06.2014


Ответы (1)


В Python списки изменяемы. Поэтому, когда вы вызываете perms(a, k+1) внутри perms, вы получаете точно такой же экземпляр a внутри рекурсивного вызова. Рассмотрим этот пример:

>>> a = []
>>> b = [4,5,6]
>>> a.append(b)
>>> print a
[[4, 5, 6]]
>>> b.append(7)
>>> print a
[[4, 5, 6, 7]]

Как видите, непосредственное редактирование списка b также редактирует b, который был добавлен к списку a, потому что и b, и a[0] ссылаются на один и тот же объект:

>>> b is a[0]
True

Вы не видите такого поведения со строками, которые неизменяемы:

>>> a = []
>>> b = "hi"
>>> a.append(b)
>>> print a
['hi']
>>> b = "blah"
>>> print a
['hi']

>>> b is a[0]
False

Вы можете исправить проблему в своем коде, передав копию списка a в рекурсивный вызов, например:

perms(a[:], k+1)
person dano    schedule 06.06.2014