简体   繁体   English

如何在 python 中缩短这段代码? (运行真的很慢)

[英]How can I make this code shorter in python? (it runs really slow)

import random, re
score = 0
i = 1
while i < 11:
    ops = ["-","+","*"]
    num1, num2, operation, userans = random.randint(1,4),random.randint(5,12),random.choice(ops),"",
    q = (str(num1) + operation + str(num2) + ":   ")
    while userans == "" or not re.match(r'^[0-9-]*$', userans):
     userans = input(q)

    if operation == '+':
        product = num1+num2 
    elif operation == '-':
        product = num1-num2
    elif operation == '*':
        product = num1*num2

    if str(product) == userans:
        print ("you are correct!")
        score = score + 1
    else:
        print("You are incorrect! The correct answer was " + str(product))

    print ("Your score is " + str(score))
    i=i+1

This is the code I have but I need it to be less laggy.这是我拥有的代码,但我需要它不那么滞后。 Also the program is a random question generator该程序也是一个随机问题生成器

Trying to fit the spirit of your question, and to flesh out the comments saying it's unnecesary (it is), I nerfed your script so it always reads '20' from the user (which is sometimes correct) and just builds the output strings but doesn't print them, so I could run it through the timeit module.试图符合你的问题的精神,并充实评论说它是不必要的(它是),我削弱了你的脚本,所以它总是从用户那里读取“20”(有时是正确的)并且只是构建输出字符串但是不打印它们,所以我可以通过timeit模块运行它。

Start: 20,000 runs in ~1.47 seconds.开始:约 1.47 秒内运行 20,000 次。

  • from random import choice, randint to make them local names for faster lookup, same with re.match , improvement ~0.04 seconds over the 20,000 runs. from random import choice, randint使它们成为本地名称以加快查找速度,与re.match相同,在 20,000 次运行中改进了 ~0.04 秒。
  • Move the ops list creation outside the loop, ~0.03s将 ops 列表的创建移到循环之外,~0.03s
  • Changing the regex to match "[^0-9-]" instead, ~0.07s更改正则表达式以匹配“[^0-9-]”,~0.07s
  • Not computing str(product) twice, ~0.01s不计算 str(product) 两次,~0.01s
  • Changing the nested while condition to while not userans.isdigit(): , which is probably good enough for positive whole number answers, ~0.31s将嵌套的 while 条件更改为while not userans.isdigit(): ,这对于正整数答案来说可能已经足够了,~0.31s
    • Whoops subtraction might mean negative answers, so that isn't quite right.哎呀减法可能意味着否定答案,所以这不太正确。 Could replace with this but it's fine for now - not invoking regexes is the biggest step performance gain.可以用这个代替但现在很好 - 不调用正则表达式是最大的一步性能提升。
  • Calculate the product before asking the user for their input, so there's less work going on between reading their input and knowing the answer, ~unknown, might shorten the give answer-get response gap.在询问用户输入之前计算产品,因此在阅读他们的输入和知道答案之间的工作较少,〜未知,可能会缩短给出答案-得到响应的差距。
  • Tweak the way the calculations are done and checked, a touch slower, but less code repetition so it's shorter, as asked, but it's also uglier and harder to read.调整计算的完成和检查方式,稍微慢一点,但代码重复更少,所以它更短,正如所要求的那样,但它也更难看,更难阅读。

Finish: 20,000 runs in ~0.996 seconds.完成:约 0.996 秒内运行 20,000 次。

Result: 1/3rd faster!结果:快 1/3! Hooray!万岁! If my version is 100%, yours is 150%.如果我的版本是 100%,那么你的版本是 150%。 If my version is harder to read, well so be it.如果我的版本更难阅读,那就这样吧。

from random import randint, choice
from re import match

score = 0
i = 1
ops = ["-","+","*"]
ops2 = {"-":sub,"+":add,"*":mul}

while i < 11:
    num1, num2, operation, userans = randint(1,4),randint(5,12),choice(ops),"",
    q = (str(num1) + operation + str(num2) + ":   ")

    product = str(ops2[operation](num1, num2))

    while not userans.isdigit():
     userans = input(q)

    if userans == product:
        print("you are correct!")
        score = score + 1
    else:
        print("You are incorrect! The correct answer was " + product)

    print("Your score is " + str(score))
    i=i+1

but

we're talking 0.5 seconds faster over 20,000 runs.我们说的是在 20,000 次运行中快了 0.5 秒。 0.000025 seconds per 10 question run.每 10 个问题运行 0.000025 秒。 0.0000025 seconds faster per question/answer.每个问题/答案快 0.0000025 秒。

With random numbers involved, this is pretty much measurement noise.涉及随机数,这几乎是测量噪声。 This tiny amounts of change could be significantly affected by different versions of the Python runtime doing slightly different things internally.这种微小的变化可能会受到不同版本的 Python 运行时在内部做一些稍微不同的事情的显着影响。

2.5 micro seconds, is it? 2.5 微秒,是吗? Oft quoted figures say humans feel things are "instant" at around 10-100 milliseconds. 经常引用的数字说,人类感觉事物在大约 10-100 毫秒内是“即时的”。

Your code is already way way way fast enough not cause it to feel laggy.你的代码已经足够快了,不会让它感觉滞后。

If it feels laggy, it's probably a network involved - running the code on a remote computer over SSH or Remote Desktop, or over the internet in a web browser.如果感觉滞后,则可能是涉及网络 - 通过 SSH 或远程桌面在远程计算机上运行代码,或者在 Web 浏览器中通过 Internet 运行代码。 Or it's a broken terminal client or web based terminal which struggles with basic text input/output.或者它是一个损坏的终端客户端或基于 Web 的终端,它在基本文本输入/输出方面遇到了困难。

Instead, fix it a bit for readability - like counting from 1 to less-than-11 as a way to loop ten times.取而代之的是,稍微修复它以提高可读性 - 就像从 1 数到小于 11 作为循环十次的方式。 Change the "*" to "+" in the regex and lose the "userans = """ check, cut out some of the str() going on, don't call it "product" when it could be a sum or a difference.将正则表达式中的“*”更改为“+”并丢失“userans =“””检查,去掉一些正在进行的 str() ,当它可能是一个总和或一个时不要称它为“产品”区别。

from random import randint, choice
import re

score = 0
operations = ["-", "+", "*"]

for turn in range(10):

    num1 = randint(1,4)
    num2 = randint(5,12)
    operation = choice(operations)
    q = "{0} {1} {2}:  ".format(num1, operation, num2)

    userans = ""
    while not re.match('^[0-9-]+$', userans):
        userans = input(q)

    if operation == '+':
        result = num1 + num2 
    elif operation == '-':
        result = num1 - num2
    elif operation == '*':
        result = num1 * num2

    result = str(result)


    if result == userans:
        print ("you are correct!")
        score = score + 1
    else:
        print("You are incorrect! The correct answer was " + product)

    print ("Your score is " + str(score))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM