Что именно массив [:] делает в этом алгоритме возврата, а точнее в Python? - PullRequest
1 голос
/ 01 марта 2020

Итак, я решал (или, скорее, смотрю на решение хаха) вопрос о Leetcode , и это было решение, позволяющее вам генерировать все возможные перестановки массива с уникальными целыми числами.

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:

        length = len(nums)
        results = []

        def backtrack(first_char_index):
            if first_char_index == length:
                # print(nums == nums[:])
                results.append(nums)

            for index in range(first_char_index, length):
                nums[first_char_index], nums[index] = nums[index], nums[first_char_index]
                backtrack(first_char_index + 1)
                nums[first_char_index], nums[index] = nums[index], nums[first_char_index]

        backtrack(0)
        return results

Итак, я тестировал решение и понял, что это решение работает, только если внутри условия if внутри функции backtrack я использую results.append(nums[:]) вместо вышеуказанного results.append(nums).

Итак, я сначала подумал, что это, вероятно, потому, что nums[:] следует использовать, потому что нам нужно сгенерировать новую копию, но затем я добавил этот оператор print до results.append(nums) и обнаружил, что все печати заявления дали мне True результат.

Я помню, как видел несколько решений с такой схемой наличия nums[:] вместо nums, и хотел бы спросить, может ли кто-нибудь пролить свет на то, что именно делает дополнительные [:] делать? Я знаю, что он создает новую копию (т.е. другой объект, но с тем же значением), но, поскольку он имеет то же значение, почему это приводит к другому результату?

Чтобы проиллюстрировать это, результат с вводом [1, 2, 3] дает

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

при использовании nums и

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

(правильный ответ) , при использовании nums[:].

Заранее спасибо!

РЕДАКТИРОВАТЬ: По какой-то причине этот вопрос признан таким же, как и другие, которые касаются глубокой / мелкой копии. Тем не менее, я предполагаю, что я спрашиваю здесь о том, что, поскольку [:] приводит к новому, другому объекту с таким же значением и с тем фактом, что значение nums и nums[:] то же самое (он печатает, чтобы быть измененным значением), разве он не должен добавлять массив с измененным значением вместо исходного нетронутого nums массива?

1 Ответ

3 голосов
/ 01 марта 2020

nums и nums [:] действительно имеют одно и то же значение (которое вы проверяете с помощью ==), но это разные объекты (которые вы можете проверить с помощью ключевого слова 'is'). Последовательности являются изменяемыми, поэтому вы можете изменять содержащиеся в них значения, не изменяя сам объект. [:] Просто создает копию существующей последовательности. Таким образом, у вас есть другой объект со всеми значениями предыдущего

РЕДАКТИРОВАТЬ: причина в том, что, когда вы добавляете числа к результатам, числа все еще могут быть изменены, даже если они находятся внутри результатов. Поэтому элементы внутри результатов будут меняться каждый раз, когда вы меняете исходные числа (фактически, в результате все значения идентичны). Если вы создадите копию для каждого элемента, который вставляете в результаты, вместо этого все элементы будут иметь разные значения.

...