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循环中每次都生成相同的随机数?

9 回复

你这么写
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.

真的很感谢,不仅仅是感谢提供的答案,更重要的是提供了解决问题的思路,真的很棒

感谢感谢 明白了

回到顶部