Why does my function overwrite a list passed as a parameter?

前端 未结 4 659
温柔的废话
温柔的废话 2020-12-20 18:14

I have created a function that takes a list as a parameter. It shuffles the list, replaces the first element and returns the new list.

import random
firstLi         


        
4条回答
  •  轮回少年
    2020-12-20 18:56

    As you found out, random.shuffle mutates the list in place:

    random.shuffle(x[, random])

    Shuffle the sequence x in place. The optional argument random is a 0-argument function returning a random float in [0.0, 1.0); by default, this is the function random().

    Note that for even rather small len(x), the total number of permutations of x is larger than the period of most random number generators; this implies that most permutations of a long sequence can never be generated.

    Strings are immutable in Python, all string operations return a new string instead. This is the "string" example from your question:

    string="a"
    
    def substitute_string(foo):
        foo = 'b'
        return foo
    

    It is not really akin to the code from the substitution list in the first code block of the question. The equivalent code using a list would be this:

    alist = [1, 2, 3]
    
    def substitute_list(foo):
        foo = [4, 5, 6]
        return foo
    

    And it works identically:

    >>> alist
    [1, 2, 3]
    
    >>> substitute_list(alist)
    [4, 5, 6]
    
    >>> alist
    [1, 2, 3]
    

    Back to your solution, it could be:

    def substitution_and_copy(imported_list):
        imported_list = imported_list[:]
        random.shuffle(imported_list)
        imported_list[0]="WORD"
        return imported_list
    

    And no, assigning a new value to the argument will not mutate the original list, the same way you don't mutate the original string when you assign a new value to foo (also changed camelCase to snake_case, I'm a little nazy about PEP8).

    [update]

    What you have now, however, is what he already tried. "I have found a workaround by copying the list within the function, but it seems inefficient"

    A list copy is not as inefficient as you may think, but this is not the point: as someone else pointed out, either you mutate the list in place and return nothing or return a new list - you can't have your cake and eat it.

提交回复
热议问题