python - 是否有一种 Pythonic 的方式来跳过 for 循环中的 if 语句以使我的代码运行得更快?
问题描述
我正在用 Python 编写一个脚本,该脚本本质上是掷骰子并检查掷骰子是否超过数字x
。我想重复这个过程n
次数并获得骰子超过数字的概率x
。例如
Count = 0
for _ in itertools.repeat(None, Iterations):
x = 3
die_roll = rnd.randint(1,6)
if die_roll > x:
Count += 1
Probability_of_exceed = Count / Iterations
我想根据用户输入同时修改骰子和 x。此用户输入将选择不同的例程来修改脚本,例如"Andy's_Routine"
可能更改x
为4
. 目前,我在 for 循环中使用 if 语句来检查哪些例程处于活动状态,然后应用它们,例如
Count = 0
for _ in itertools.repeat(None, Iterations):
x = 3
if "Andy's_Routine" in Active_Routines:
x = 4
die_roll = rnd.randint(1,6)
if "Bill's_Routine" in Active_Routines:
die_roll += 1
if "Chloe's_Routine" in Active_Routines:
# do something
pass
if "Person_10^5's_Routine" in Active_Routines:
# do something else
pass
if die_roll > x:
Count += 1
Probability_of_exceed = Count / Iterations
在实践中,例程并不是那么简单,以至于它们可以被概括,例如,它们可能会添加额外的输出。这些例程可以同时执行。问题是可能有数千个不同的例程,因此每个循环将花费大部分时间检查 if 语句,从而减慢程序的速度。
有没有更好的方法来构造代码来检查哪些例程只使用一次,然后以某种方式修改迭代?
解决方案
你在这里问了两件事——你希望你的代码更加 Pythonic,并且你希望它运行得更快。
第一个更容易回答:制作Active_Routines
一个函数列表而不是字符串列表,然后从列表中调用函数。由于这些函数可能需要更改本地状态(x
和die_roll
),您需要将状态作为参数传递给它们,并让它们返回一个新状态。重构可能如下所示:
def Andy(x, die_roll):
return (4, die_roll)
def Bill(x, die_roll):
return (x, die_roll + 1)
def Chloe(x, die_roll):
# do something
return (x, die_roll)
Active_Routines = [Andy, Bill, Chloe]
Count = 0
for i in range(Iterations):
x = 3
die_roll = rnd.randint(1,6)
for routine in Active_Routines:
x, die_roll = routine(x, die_roll)
if die_roll > x:
Count += 1
Probability_of_exceed = Count / Iterations
第二个更难回答。这种重构现在进行了大量的函数调用,而不是检查if
条件;所以可能会有更少的错过分支预测,但更多的函数调用开销。您必须对其进行基准测试(例如使用timeit 库)才能确定。但是,至少这段代码应该更容易维护。
推荐阅读
- python - Web Scraping - 从 href 递归调用链接,遍历存储数据
- python - 如何在 python 中从 Web 下载 xlsx 文件
- java - CodecNotFoundException:未找到请求操作的编解码器:['org.apache.cassandra.db.marshal.ByteType' <-> byte]
- android - 通过恢复下载使用 Azure 存储下载文件
- ios - 如何从 pass Sender ID 中获取 FCMToken?
- git - 詹金斯中带有逻辑的动态分支
- jenkins-x - Jenkinsx - 503 服务临时可用
- python - 带有参数的装饰器作为另一个 Python 类中的类方法
- java - 如何根据类设置值
- ruby-on-rails - 如何在选择标签内链接到部分?