在 for 循环中删除元素

Remove elements while in a for loop

我有一个简单的纸牌游戏,我目前正在为我的论文工作。 规则很简单。您有一副 52 张牌,从 1 到 10 以及杰克、皇后、马。 你从牌组抽一张牌。如果它是一个数字,它将被添加到您的帐户中。如果您抽到 J、Q 或马,您的帐户将重置为 0。每次抽奖后,您可以决定是要再次抽奖还是停止抽奖。

对于这个游戏,我在这个网站的帮助下编写了一个代码。 它应该给出准确绘制 "target" 的概率。 因此,例如抽奖的概率,这样您的帐户中就有 1 个积分, 是 4/52,因为你有四个 1。 Programm 确实给了我这个值。

但是您帐户中恰好有 2 个积分的概率是 4/52 + 4/52*3/51。您可以画一个 2,概率为 4/52,或者一个 1 和另一个 1,概率为 4/52*3/51。 这里的代码搞砸了。它计算您的帐户中恰好有 2 个点的概率 4/52 + 4/52*4/51 我不明白为什么?

谁能帮帮我?

 import collections
 import numpy as np


def probability(n, s, target):
    prev = {0: 1}  # previous roll is 0 for first time
    for q in range(n):
        cur = collections.defaultdict(int)  # current probability
        for r, times in prev.items():
            cards = [card for card in range(1, 11)] * 4
            for i in cards[:]:
                cards.remove(i)
                # if r occurred `times` times in the last iteration then
                # r+i have `times` more possibilities for the current iteration.
                cur[r + i] += times
        prev = cur  # use this for the next iteration
    return (cur[t]*np.math.factorial(s-n)) / (np.math.factorial(s))


if __name__ == '__main__':
    s = 52
    for target in range(1, 151):
        prob = 0

        for n in range(1, 52):
            prob += probability(n, s, target)
        print(prob)

编辑:我很确定,那行

for i in [i for i in cards]:

是问题所在。因为cards.remove(i)移除抽到的牌,但我不在乎,反正可以抽到。

编辑 2:仍在搜索。我尝试了这两个问题中的建议

How to remove list elements in a for loop in Python?

How to remove items from a list while iterating?

没有达到应有的效果。

我假设你想用 probability(n, s, target) 来计算你从 s 张卡片中恰好抽出 n 个值的总和恰好是 target 的概率。 那么你就会遇到n>=2的问题。如果我没理解错的话,对于循环中的每一次迭代

for q in range(n):

你在 cur[sum] 中保存了抽一张牌 (p=0)、两张牌 (p=1) 等后达到总和的方法数。但是当你设置 p=1 时,你不会 "remember" 你在设置

时已经画了哪张牌

cards = [i for i in range(1, 11)] * 4

之后。因此,如果您先抽到了“1”(四种可能性),您仍然可以从牌组中抽出四个“1”,这将为您提供 4/52*4/51。

作为旁注: 如果 i==11 是否应该进行某种检查,因为这应该重置您的帐户?

我已经解决了。大约 4 天后。

这是代码:

import numpy as np


def probability(cards, target, with_replacement = False):
    x = 0 if with_replacement else 1

    def _a(idx, l, r, t):
        if t == sum(l):
            r.append(l)
        elif t < sum(l):
            return
        for u in range(idx, len(cards)):
            _a(u + x, l + [cards[u]], r, t)
        return r
    return _a(0, [], [], target)


if __name__ == '__main__':
    s = 52  # amount of cards in your deck
    cards = [c for c in range(1, 11)] * 4
    prob = 0
    for target in range(1, 151):  # run till 150 points
        prob = probability(cards, target, with_replacement = False)
        percentage = 0
        for i in range(len(prob)):
            percentage += np.math.factorial(len(prob[i])) * np.math.factorial(s-len(prob[i]))/(np.math.factorial(s))
        print(percentage)

此代码是我的问题的解决方案。因此可以关闭此线程。 对于那些想知道它作为 tl;dr 版本的功能的人。

您有一个列表(在本例中为卡片)。该代码为您提供了列表中元素的所有可能组合,例如元素的总和等于目标值。此外,它还给出了上述纸牌游戏中绘制特定值的概率。上面提到的游戏基本上是猪骰子游戏,但有纸牌。