【发布时间】:2016-05-27 16:32:00
【问题描述】:
我创建了一个将列表作为参数的函数。它打乱列表,替换第一个元素并返回新列表。
import random
firstList=["a","b","c","d","e","f","g","h","i"]
def substitution(importedList):
random.shuffle(importedList)
importedList[0]="WORD"
return importedList
洗牌对我的问题没有影响。然而,令我惊讶的是,返回的 importList 覆盖了原来的 firstList。
>>> firstList
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
>>> substitution(firstList)
['WORD', 'a', 'b', 'd', 'i', 'c', 'g', 'e', 'h']
>>> firstList
['WORD', 'a', 'b', 'd', 'i', 'c', 'g', 'e', 'h']
我通过在函数中复制列表找到了一种解决方法,但它似乎效率低下。
import random
firstList=["a","b","c","d","e","f","g","h","i"]
string="a"
def substitutionandcopy(importedList):
copiedList=importedList[:]
random.shuffle(copiedList)
copiedList[0]="WORD"
return copiedList
我的问题是为什么函数会替换 firstList?例如,如果它是一个字符串,则不会发生这种情况。
string="a"
def substituteString(foo):
foo='b'
return foo
>>> string
'a'
>>> substituteString(string)
'b'
>>> string
'a'
【问题讨论】:
-
1.
shuffle改变了原来的可变列表。 2.传递列表的copy而不是原来的。见How to clone or copy a list in Python? -
字符串是不可变的,列表是可变的。按照@BhargavRao 的建议传递一份副本。
-
这可能是一种品味,但我宁愿让函数复制列表并处理副本,而不是我必须传递副本。可以通过您可以传入的类型使函数更加灵活。(例如,您可以传入元组而不是列表)。
-
来自 Bhargav 的链接:“当您说
new_list = my_list时,您不是在复制,您只是在添加另一个指向内存中原始列表的名称”。作为函数参数传递的列表也是如此。 -
如果你想要的是复制,那么明确地复制显然不是低效——可以这么说,你不能不做就做:-)