为啥一个变量(随机数)的行为就像一个“发电机”

Posted

技术标签:

【中文标题】为啥一个变量(随机数)的行为就像一个“发电机”【英文标题】:Why does a variable (random number) act like a 'generator'为什么一个变量(随机数)的行为就像一个“发电机” 【发布时间】:2021-12-11 20:55:50 【问题描述】:

我正在尝试在python上做一个简单的石头剪刀布游戏

TypeError: unsupported operand type(s) for +: 'generator' and 'str'

这是我在代码中放置随机发生器后给出的错误消息:

Traceback (most recent call last)

<ipython-input-4-dea4c40cfdcd> in <module>()
 49   if key == 'q':
 50     break
---> 51   player_score, comp_score = gameplay(player_score, comp_score)
 52   print('Score is: YOU ', player_score, ' - ', comp_score, ' COMPUTER')
 53   print('')

 <ipython-input-4-dea4c40cfdcd> in gameplay(player_score, comp_score)
 12 
 13   comp_move = moves[randomize]
 ---> 14   battle = key + '-' + comp_move
 15 
 16   comp_print = (word for position, word in ['rock', 'paper', 'scissors'] if position == randomize - 1)

这个“生成器”对象是什么?在谷歌他们说它是由使用循环制成的,所以它是一种序列,但不是用循环而不是while循环生成的。这个循环是错误的原因吗?而且,我没有使用字母序列,而只是其中的一个字母,并且我用它在序列中的位置编号来调用它?

这是直到出现错误的代码:

 from random import randint

 player_score = 0
 comp_score = 0
 key = None

 # Setting the rules
 choices = 'r-s': 'rock breaks scissors', 'p-r': 'paper envelopes rock', 's-p': 'scissors cut paper'
 moves = 1: 'r', 2: 'p', 3: 's'

 def gameplay(player_score, comp_score):

   comp_move = moves[randomize]
   battle = key + '-' + comp_move

以下是有关代码的更多详细信息: 随机数在while循环中初始化

while True:
  randomize = randint(1, 3)
  print('<r>ock, <p>aper or <s>cissors? Press any key to continue; <q> for exit')
  key = check_input()
  if key == 'q':
    break
  player_score, comp_score = gameplay(player_score, comp_score)
  print('Score is: YOU ', player_score, ' - ', comp_score, ' COMPUTER')
  print('')
  key = None

但是,我在这里使用的是单个变量而不是变量序列,还是我错了?


就我在 Python 中查找数组的答案和解释而言,到目前为止,我已经找到了两种不同的方法来解决这个问题:

第一个是通过@John Coleman 的示例使用“for 循环”并使用数组索引简化表达式:

items = ['rock', 'paper', 'scissors']

  for word in items:
    if items.index(word) == randomize - 1:
      print('Computer played: ', word)

另一种方法是改善表达方式

item = (word for position, word in ['rock', 'paper', 'scissors'] if position == randomize - 1)

使用函数“枚举”:

  item = [word for position, word in enumerate(['rock', 'paper', 'scissors']) if position == randomize - 1]
  print('Computer played: ', item[0])

其实问题首先出现的原因是Python中缺少数组的索引,所以你得自己摸索如何制作。

两个给定的解决方案都有效,因此该主题可以被视为“封闭”。

【问题讨论】:

comp_print 的类型为 generator,因为您使用生成器表达式来定义它。目前尚不清楚comp_move(真的,moves[randomize])如何变成generator 您需要向我们展示在错误发生时有效的 key 的值 - 您发布的代码中唯一的赋值是 None,这会产生完全不同的错误,所以它一定是在其他地方重新分配的。 Generator 是 python 的一个基本(和有用的)概念——它本质上是一个在你迭代它时生成值的对象。 python 中的一些理解表达式和内置函数会生成生成器。您可以将有限生成器转换为列表或元组以查看列表(生成器)中的内容。或者你可以 next(iter(generator)) 来查看下一个元素。 您从未在发布的代码中定义randomize。请提供minimal reproducible example。您没有提供足够的信息让任何人了解问题所在。 请编辑问题以包含相关代码 inputed = (letter for position, letter in ['p', 'q', 'r', 's'] if letter == inputed) 导致 inputed 成为生成器表达式(实际上没有意义),然后您将其返回。 key 如何成为生成器。 【参考方案1】:

您的check_input 过于复杂,并且无意中返回了一个生成器对象(如果您尝试使用它还会引发错误)。

相反,只需执行以下操作:

def check_input():
  while True:
    inputed = input('Press a key: <r>, <p>, <s>, or <q>')
    if inputed  in ['p', 'q', 'r', 's']:
        return inputed
    print('Wrong input! Press a key: <r>, <p>, <s>, or <q>')

【讨论】:

是的,这给出了一个非常简单且有效的问题解释。但是,这部分代码存在相同类型的错误:comp_print = (word for position, word in ['rock', 'paper', 'scissors'] if position == randomize - 1) print('Computer播放:',comp_print)。这就是它在控制台中返回的内容:ock、

aper 还是 cissors?按任意键继续; 退出 按一个键:

r 玩过的计算机:. at 0x7ff78a33a8d0> comp wins Score is: YOU 0 - 1 台电脑

我试图对第二部分做同样的事情,但会发生以下情况:``` 表示位置,['rock', 'paper', 'scissors'] 中的单词:如果 position = = randomize - 1: print('电脑播放:', word)``` ValueError: too many values to unpack (expected 2) 现在该怎么办??!

以上是关于为啥一个变量(随机数)的行为就像一个“发电机”的主要内容,如果未能解决你的问题,请参考以下文章

为啥顺序写入比 HDD 上的随机写入快

工厂松饼发电机列表

随机变量X,Y独立,则X²与Y²,X与Y²,X²与Y,等等为啥为啥都独立?

用于设置变量的移动参数-模型行为更改

样本方差为啥要除n-1,而不是n

为啥 C++ 共享指针的行为不像迭代器的标准指针?