将列表设为函数默认参数后随机生成器输出重复值的原因
问题
我原本有一个生成10个随机数的函数,代码如下:
import random def number_generate(): numbers=[] while len(numbers)<10: a=int(random.random()*10) numbers.append(a) return numbers for i in range(1000000): if i%100000==0: print(number_generate())
该函数原本运行正常,直到我将初始列表改为函数的默认参数,修改后的代码如下:
import random def number_generate(numbers=[]): while len(numbers)<10: a=int(random.random()*10) numbers.append(a) return numbers for i in range(1000000): if i%100000==0: print(number_generate())
现在每次生成的随机数都完全相同,请问这两段代码的差异是什么?能否解释该现象?
差异与现象解释
核心差异
- 原代码:每次调用
number_generate时,都会在函数内部新建一个空列表numbers,后续所有随机数都往这个全新的列表里添加,最终返回的是包含10个新随机数的独立列表。 - 修改后的代码:把空列表
[]设为函数的默认参数,这个默认列表只会在函数定义的那一刻创建一次,而非每次调用函数时重新生成。
现象原因
第一次调用number_generate()时,默认的空列表会被填充至10个随机数,之后这个列表会作为函数的一部分被持续保留(Python函数的默认参数属于函数对象的属性,不会随调用销毁)。后续再调用number_generate()时,传入的依然是这个已经有10个元素的旧列表,while len(numbers)<10的条件直接不成立,函数会直接返回这个旧列表,所以每次输出的随机数完全相同。
如果要修复这个问题,可以把默认参数设为None,再在函数内部判断并创建新列表:
import random def number_generate(numbers=None): if numbers is None: numbers = [] while len(numbers)<10: a=int(random.random()*10) numbers.append(a) return numbers
内容的提问来源于stack exchange,提问作者maynak
相关产品推荐
相关产品推荐

