【问题标题】:D&D dice program (without loop)DnD 骰子程序(无循环)
【发布时间】:2019-03-04 18:09:43
【问题描述】:

我应该编写一个程序来掷骰子五次,但我不能有任何冗余,也不能使用任何类型的循环。 我将在此处粘贴练习中的文本。 “构建一个 python 应用程序,以便提示用户输入骰子的面数(龙与地下城风格的骰子!) 在此之后,它将掷骰子五次,并将所有五个结果输出给用户 掷骰子五次将需要五个重复的代码块——通过使用用户定义的函数掷骰子来消除这种冗余

谁能帮帮我?

import random

def main():

    diceType = int(input("Enter how many sides the dices will have: "))

    diceRoll1 = random.randint(1,diceType)
    diceRoll2 = random.randint(1,diceType)
    diceRoll3 = random.randint(1,diceType)
    diceRoll4 = random.randint(1,diceType)
    diceRoll5 = random.randint(1,diceType)

    print("The dices read", diceRoll1, diceRoll2, diceRoll3, diceRoll4, diceRoll5)

main()

【问题讨论】:

  • 为什么需要在没有循环的情况下这样做?
  • 这是来自课堂的挑战。
  • 你应该使用itertools 模块吗?
  • 根据您如何定义“任何类型的循环”和冗余,这项任务介于微不足道和不可能之间。
  • 大多数类似这样的挑战指定你可以使用什么;例如,您应该进行递归吗?

标签: python dice


【解决方案1】:

我会使用itertools 模块。

>>> from itertools import islice, imap, repeat
>>> from random import randint
>>> diceType = 5
>>> list(islice(imap(random.randint, repeat(1), repeat(diceType)), 5))
[5, 5, 4, 5, 4]

repeat 创建无限的 1 和 diceTypes 序列。 imap 创建调用 randint(1, diceType) 的结果的无限序列(每次调用都会提取 repeat(1)repeat(diceType) 的下一个值作为参数。islice 生成一个有限迭代器,它只接受前 5 个元素无限序列,list 实际上从有限迭代器中获取值。

按照相同的思路,不使用itertools,如下(为简单起见,使用Python 2 的map 版本):

map(lambda f: f(1, diceType), [randint]*5)

这将创建一个包含 5 个对 randint 的单独引用的列表,然后映射一个函数,该函数在该列表上调用 1 和 diceType 的参数。

(实际上,itertools 版本可以使用相同的方法进行简化:

list(islice(map(lambda f: f(1, diceType), repeat(randint)), 5))

)

【讨论】:

  • 谢谢chepner!那太棒了!但我不能使用列表,因为它还没有被教过。 :-(
  • 如果您不能使用循环或列表,我迫不及待想听听您的老师的想法。
【解决方案2】:

就我个人而言,如果我不能使用任何循环,我会使用一个列表来跟踪已使用和未使用的内容。

diceType = int(input("Enter how many sides the dices will have: "))
lyst = range(1,diceType+1)

diceRoll1 = random.choice(lyst)
lyst.remove(diceRoll1)
diceRoll2 = random.choice(lyst)
lyst.remove(diceRoll2)
diceRoll3 = random.choice(lyst)
lyst.remove(diceRoll3)
diceRoll4 = random.choice(lyst)
lyst.remove(diceRoll4)
diceRoll5 = random.choice(lyst)
lyst.remove(diceRoll5)

print("The dices read", diceRoll1, diceRoll2, diceRoll3, diceRoll4, diceRoll5)

这不是最优雅的解决方案,但我喜欢它的可读性。您从列表中选择了某些内容,然后将其删除。然后再做 4 次。

【讨论】:

  • 谢谢朱莉!不幸的是,我想我不能使用 lyst,因为它还没有被教过。
【解决方案3】:

使用理解列表

import random
randomList = [random.randint(1,diceType) for _ in range(5)]
diceRoll1, diceRoll2, diceRoll3, diceRoll4, diceRoll5 = randomList

【讨论】:

  • 我会说这仍然算作使用循环,列表理解只是使用 for 循环填充列表的快捷方式
  • @BigGerman 这取决于OP所指的循环,但是是的,在字节码中有一个循环
  • 是的,它被认为是一个循环。还是谢谢!
【解决方案4】:

注意:这是一种糟糕的方法。循环的目的是消除冗余。如果没有任何类型的循环,所有解决方案都将是 hacky、难以阅读并且可能效率低下。

import random

def roll5(diceType, remaining_roll=5):

    if remaining_roll == 0:
        return []

    retval = roll5(diceType, remaining_roll - 1)
    retval.append(random.randint(1,diceType))
    return retval

diceType = int(input("Enter how many sides the dices will have: "))

diceRoll1, diceRoll2, diceRoll3, diceRoll4, diceRoll5 = roll5(diceType)
print("The dices read", diceRoll1, diceRoll2, diceRoll3, diceRoll4, diceRoll5)

【讨论】:

  • 虽然这可能是一个有效的解决方案,但取决于谁来判断,我认为递归函数是一种循环。带有尾调用优化的语言可以使带有递归调用的代码与带有循环的代码相同。
  • 感谢塞尔柱!这里的重点是程序不需要高效或易于阅读。用于学习目的。
  • @JohanL 不要将“循环”与“重复”混淆;循环是给定语言中用于重复执行代码块的句法结构。
  • @chepner 这是一个有效点,但它要求您根据软件中使用的正常定义将“任何类型的循环”限制为循环。不过,也许这是合理的。但“任何一种……”的意义相当深远。
  • 我会说变量列表是多余的。也许使用print("The dices read", *roll5(diceType)) 而不是最后两行?
猜你喜欢
  • 1970-01-01
  • 2014-05-12
  • 2017-02-23
  • 1970-01-01
  • 2017-09-30
  • 1970-01-01
  • 2012-11-27
  • 2014-04-21
  • 2013-08-02
相关资源
最近更新 更多