Python中为什么randint()作为参数传入后,在for循环中每次都生成相同的随机数?
# -*- coding:utf-8 -*-
import random
import collections
result = {
1: 0,
2: 0,
3: 0,
4: 0,
}
def test(b=random.randint(1, 5)):
global result
if b == 1:
result[1] += 1
elif b == 2:
result[2] += 1
elif b == 3:
result[3] += 1
elif b == 4:
result[4] += 1
if name == “main”:
for i in range(1000):
test()
print(result)
{1: 1000, 2: 0, 3: 0, 4: 0}
每次都只是不同的一个数字跑 1000 遍,感觉像是 list 作为形参的时候,可变对象的问题。但是 randint 本身打印出来就是一个 int 类型,求助大佬指教指教
Python中为什么randint()作为参数传入后,在for循环中每次都生成相同的随机数?
你这么写
def test(b=random.randint(1, 5)):
等同于
b=random.randint(1, 5)
def test(b):
这问题挺常见的,其实不是randint()在循环里出问题,是你传参的方式不对。
看这段典型的问题代码:
import random
def roll_dice(times, result=random.randint(1, 6)):
for _ in range(times):
print(result)
roll_dice(5) # 会打印5次相同的数字
问题出在result=random.randint(1, 6)这里。Python的函数默认参数只在函数定义时计算一次,然后就被固定了。所以random.randint(1, 6)只在定义roll_dice函数时执行了一次,之后每次调用都使用这个固定的值。
要解决这个问题,得在循环内部调用随机函数:
import random
def roll_dice(times):
for _ in range(times):
print(random.randint(1, 6))
roll_dice(5) # 现在每次都会生成新的随机数
或者如果你确实需要把随机数生成作为参数传入,可以传函数本身:
import random
def roll_dice(times, rand_func=lambda: random.randint(1, 6)):
for _ in range(times):
print(rand_func())
roll_dice(5) # 每次调用rand_func()都会生成新随机数
简单说就是别把随机函数的结果当默认参数,要在需要的时候现调。
我也是这样改的,但就是想知道为啥,求指教
debug 路径是这样子的:
这个程序跟其他程序有什么区别-> 用了默认参数 -> 不用默认参数显式传程序就没有问题 -> 查查 python 默认参数 是怎么样做的 -> https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001374738449338c8a122a7f2e047899fc162f4a7205ea3000 -> Python 函数在定义的时候,默认参数 L 的值就被计算出来了 -> 所以 def test(b=random.randint(1, 5))的函数原型是 def test(b=一跑完这个函数定义后取到的 1-5 的随机值) -> 所以你每次调默认参数都是固定的。
问题解决。
def 的时候默认值就计算完毕了,会永久存储
比如
def pusher(item, tow=[]):
tow.append(item)
return tow
pusher(1)
pusher(2)
Python ’ s default arguments are evaluated once when the function is defined, not each time the function is called (like it is in say, Ruby). This means that if you use a mutable default argument and mutate it, you will and have mutated that object for all future calls to the function as well.
真的很感谢,不仅仅是感谢提供的答案,更重要的是提供了解决问题的思路,真的很棒
感谢感谢 明白了

