在for循环中删除元素

时间:2019-12-06 16:17:50

标签: python-3.x numpy probability combinatorics

我有一个Simpel纸牌游戏,目前正在为我的论文进行游戏。 规则是简单的。您有一副52张纸牌,从1到10,以及杰克,皇后和骑士。 您从卡组中抽出一张卡片。如果是数字,它将被添加到您的帐户中。如果您绘制千斤顶,皇后或骑士,您的帐户将重置为0。每次绘制之后,您都可以决定是否要重新绘制或停止。

对于这个游戏,我在这个站点的帮助下编写了代码。 它应该给出绘制精确“目标”的概率。 举例来说,抽奖的可能性使您的帐户中有1点, 是4/52,因为您有四个1´。程序确实给了我这个价值。

但是。您的帐户中恰好有2分的概率是 4/52 + 4/52 * 3/51。您可以绘制2的概率为4/52的2或绘制1,再绘制1的概率为4/52 * 3/51的1。 这里的代码搞砸了。它计算出您的帐户中恰好有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?

没有任何效果。

2 个答案:

答案 0 :(得分:0)

我假设使用概率(n,s,target)来计算概率,如果您从s张卡中准确抽取n张值的总和正是目标。 然后,您将遇到n> = 2的问题。如果我理解这一权利,那么对于循环中的每个迭代

  

对于范围(n)中的q:

您现在节省了得出一张牌(p = 0),两张牌(p = 1)等后求和的方式。但是,当您设置p = 1时,您不会“记住”设置时已经抓过的纸牌

  

纸牌= [i代表i在范围(1,11)中]] * 4

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

请注意: 应该不会对i == 11进行某种检查,因为那会重置您的帐户?

答案 1 :(得分:0)

我已经解决了。过了四天之后。

这是代码:

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版本的功能。

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