【问题标题】:python generator object for card dealer发牌商的python生成器对象
【发布时间】:2022-01-15 19:47:13
【问题描述】:

我的问题是创建一个一次生成一种卡片的函数。例如card_dealer() 仅输出任何一种组合,例如10S

我的尝试是

def card_dealer():
    rank = ['2','3','4','5','6','7','8','9','10','J','Q','K','A']
    suit = ['S','C','H','D']
    list3=[]
    num=0
    for i in rank[num]:
        for j in suit[num]:
            list3.append(f'{i}{j}')
            num+=1
            yield list3

next(card_dealer())

但是,当我继续运行 next(card_dealer()) 时,这只输出相同的一个组合:

['2S']

我将如何做到这一点,以便当我运行 next(card_dealer()) 时,我会得到下一个组合,例如2C。我曾考虑过使用 import random 来随机化而不是按顺序输出组合,但那是另一天! 我尝试过此代码的不同组合,例如在不同的缩进中移动产量,但它没有给出我想要的具体结果。

【问题讨论】:

  • list3num 是不必要的。

标签: python generator


【解决方案1】:

我认为这就是我更喜欢编写这个函数的方式。 card_dealer 的工作是发牌,毕竟不是套牌。

from random import shuffle


def card_dealer(deck):
    for card in deck:
        yield card

    yield None


ranks = ['2','3','4','5','6','7','8','9','10','J','Q','K','A']
suits = ['S','C','H','D']

deck = [rank + suit for suit in suits for rank in ranks]
shuffle(deck)

for card in card_dealer(deck):
    print(card or "Dealer is out of cards")

【讨论】:

  • 您不需要明确的yield None。当你到达生成器函数的末尾时,StopIteration 会自动为你提升。
  • 事实上,card_dealer 不再做任何有趣的事情了。您已经在内存中有一个列表;您不妨对其进行迭代:for card in deck:
  • @chepner 要洗牌,无论如何都必须在内存中,所以是的,for card in deck 会更容易,但 OP 要求使用生成器。 yield None 就是我想要的api,卡用光对于发牌商来说并不是个例。
  • 不管你觉得它是不是一个好的设计,它仍在提高StopIteration;这就是生成器工作的方式(以及for 循环如何知道何时停止迭代)。它只是在您执行yield None 后引发异常。您只是在每次迭代中向 card 添加了不必要的真实性测试。
【解决方案2】:

这不是 Python 中 for 循环的工作方式。我建议您查看此article 以获得良好、全面的解释,但简短的版本是您不需要这些索引。您当前的代码:

for i in rank[num]:

只在开头评估rank[num]。由于num0,因此您只会遍历字符串 '2',而不是它所属的列表。这里有一些更接近你想要的东西:

def card_dealer():
    ranks = ['2','3','4','5','6','7','8','9','10','J','Q','K','A']
    suits = ['S','C','H','D']
    for rank in ranks:
        for suit in suits:
            yield f'{rank}{suit}'

for card in card_dealer():
    print(card)

但是,这仍然会按顺序处理它们。对于随机化,您可以使用 random.shuffle 和类似的东西。 (这也使用了list comprehensionsuggested by chepneryield from 语法。每个都可以作为循环的标准。)

import random

def card_dealer():
    ranks = ['2','3','4','5','6','7','8','9','10','J','Q','K','A']
    suits = ['S','C','H','D']
    cards = [f'{rank}{suit}' for rank in ranks for suit in suits]
    random.shuffle(cards)
    yield from cards

for card in card_dealer():
    print(card)

【讨论】:

  • 更简单的是,您可以使用yield from cards 代替for 循环。
猜你喜欢
  • 2012-09-10
  • 2010-10-31
  • 2013-01-05
  • 2015-03-03
  • 2019-10-18
  • 1970-01-01
  • 2020-03-09
  • 2017-07-24
  • 2010-11-19
相关资源
最近更新 更多