自定义 random.randbool 是一个好主意吗?

3

Python没有random.randbool函数,但它有randintrandrangerandom函数。如果我想使用一个randbool函数,我可以使用以下代码:

import random
random.randbool = lambda: random.random() >= 0.5

这样做推荐吗?是否符合“Pythonic”?速度会慢很多吗?这肯定可以使以后的代码更易于理解,因为在代码中不是内联random.random() >= 0.5random.choice([False, True])可能更令人困惑。
当然,另一种选择就是使用常规函数 -
def randbool():
    return random.random() >= 0.5

哪个更好?

编辑:一些timeit基准测试:

> python -m timeit -s "import random" -s "def randbool():" -s " return random.random() >= 0.5" "randbool()
1000000 loops, best of 3: 0.275 usec per loop

> python -m timeit -s "import random" "random.random() >= 0.5"
10000000 loops, best of 3: 0.152 usec per loop

> python -m timeit -s "import random" -s "random.randbool = lambda: random.random() >= 0.5" "random.randbool()"
1000000 loops, best of 3: 0.322 usec per loop

> python -m timeit -s "import random" "random.choice([False, True])"
100000 loops, best of 3: 2.03 usec per loop

> python -m timeit -s "import random" "random.randint(0, 1)"
100000 loops, best of 3: 2.9 usec per loop

因此,最快的方法是内联,其次是常规函数,然后是定义random.randbool。而choicerandint则较慢。

10
IMO random.choice([False, True]) 非常优雅且自我解释。关于速度:为什么不测试一下呢? - vaultah
请注意,几乎没有任何情况下您不能使用整数0和1代替False和True,因此randint也可以。 - Daniel Roseman
1
在实际的代码中,我不会像这样外部修改库。将其定义在实用程序文件或其他位置,但不要添加到“random”中。 - Colonel Thirty Two
2
只是想连接到这个答案,它也建议使用random.getrandbits(1) - Matt Hall
1
这个问题非常基于个人观点,并且涉及多个不同的方面,但很可能可以通过编辑来改善。 - TylerH
3个回答

2

这是有些基于个人观点的,但我会尽量支持我的观点。

一般认为修改标准库模块是不好的做法,甚至内置函数也禁止了猴子补丁。我不这样做的主要原因是为了保持一致性。如果其他人看到你的代码(或者你以后回来看),没有任何关于random.randbool的文档或规范可以查阅。它是具有误导性的,这有点违背了python的“显式优于隐式”的口号。

相反,我建议选择最快的方法(random.random() < .5)并将其制作成一个帮助函数。由于性能似乎是一个问题,在这里是我的机器给出了一些相关示例:

In [30]: %timeit randbool()
10000000 loops, best of 3: 184 ns per loop

In [31]: %timeit random.random() < .5
10000000 loops, best of 3: 114 ns per loop

In [32]: %timeit random.randint(0,1)
1000000 loops, best of 3: 1.18 µs per loop

如果您想在帮助函数中输入一些内容,您将获得以下结果:

In [33]: %timeit bool(randbool())
1000000 loops, best of 3: 310 ns per loop

总的来说,即使有函数调用的开销(这将从修补random中获得),速度仍然相当快。

1
在Ruby中,实现mixins非常普遍,可以增强类的方法,这些方法来自标准库。很多Rails相关的东西都是这样构建的。
但我没有看到任何迹象表明这在Python中是一个好习惯。如果标准模块缺少某些功能,则通常会创建自己的模块。这样做的优点是您不需要给其他可能查看您的代码的人留下某些函数/方法来自标准集合的印象。我认为大多数Pythonistas相信他们在模块开头看到的导入。
我无法回答您的方法是否更慢。过去,我曾使用元编程来“修补”原始Python库,但那是为了确保我们有一致的接口用于测试方法。

0

你回答了自己的问题:

无论是

  1. 更易读
  2. 执行更快
  3. 更短的编写时间

都是更好的选择。这是我的优先级,你可以按照自己的需求重新排序。


没有一种选项是最易读、最快执行和最短写的。 - Sam McCreery

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接