如何将列表中后面的元素与前面的元素组合,同时保持列表的顺序先于那些后面的元素?

How do I combine later elements of a list to earlier elements, while maintaining the list’s order prior to those later elements?

长话短说,我正在掷不公平的骰子,并试图在掷 x 次后找出任何给定总和的概率。实践中有几百张脸和几百张卷,所以我不能简单地找到所有可能的组合,然后找到概率,做列表大小和内存限制。

我正在通过查找所有可能的组合及其一次出现 1 卷的概率来解决这个问题。在找到所有可能的组合和每个组合的概率后,我需要通过组合具有相同总和的组合概率来压缩它。

想想组合 (1,3) 和 (2,2) 都是独特的组合,但它们的总和都是 4,如果 (1,3) 出现的概率是 3/6,并且(2,2) 出现的概率是 1/6 总和为 4 的组合的概率是 4/6.

希望我不需要详细说明它为什么有效以及它背后的数学原理,但如果需要更多信息,请告诉我。

我已经做到了这一点,我有一个列表,其中包含掷骰后每个可能组合之一的总和,以及一个包含这些总和概率的全等列表。

对于我们的示例,它是这样的:

Sum of this rolls combos:
Sums = [6,4,2,5,4,3]
The congruent list of probabilities:
Probs = [11/36, 9/36, 7/36, 5/36, 3/36, 1/36] 

在我们的真实示例中,数字没有也不能有公分母并且是长小数,但我使用这些数字来显示我要查找的内容。

顺序很重要。我可以从总和列表中删除重复的总和,并使用以下方法维护我需要的顺序:

Condenced_sums = []
For x in sums:
    If x not in condenced_sums
        condenced_sums.append(x)  

这给了我们 Condensed_sums = [6, 4, 2, 5, 3]

我的问题是相应的概率不会消失,第一次出现的概率和任何重复出现的概率都不一样。为了确保每个总和的概率保持准确,在删除重复出现的概率之前,我需要将其添加到原始出现的概率中。 理想情况下,浓缩概率将如下所示:

Condenced_prob = [11/36, 12/36, 7/36, 5/36, 1/36]

我在想也许我可以将列表压缩在一起并得到类似的东西:

Zipped_Sum_Prob = [(6, 11/36), (4, 9/36), (2, 7/36), (5, 5/36), (4, 3/36), (3, 1/36)]

然后也许可以在列表理解语句中使用 If else 语句,但我对此还是很陌生,还没有想出一种方法来完成这项工作。

作为另一个注意事项,因为我不确定它是否会产生影响,任何总和都可能出现多次,而不仅仅是两次。

感谢任何帮助,即使它只是提出问题的更好方式。

谢谢!

编辑:

我认为提供更多关于为什么我需要维持订单的背景知识可能更有用。这是我目前所拥有的:

假设 faces = [1,2,3] #实际上这是一个具有随机值的随机长度列表 new_faces = 面孔 卷 = 随机数 prob = [.5,.333333, .1666666] #这是随机概率的全等列表。 new_prob = 概率

#en stands for enumerated.
en_new_faces = [(index_2, y_face) for index_2, y_face in enumerate(new_faces)]
en_faces = [(index_1, x_face) for index_1, x_face in enumerate(faces)]


#Why new faces? For the first roll, the possible sums are the same as the value on the faces of the die, but on the second roll we start to have combos and a number of unique sums/possible outcomes is greater than the number of faces on the original die. On the 3ed roll we need to treat each unique sum like a face of one of our dice because each unique sum can be increased by any of the values on the faces of our original die, but we don’t need to apply this to each unique combo because adding 3 to combo (2 + 2) and adding 3 to (1 + 3) gives us the same outcome. So:

new_faces = list((w,x,y,z) for w, x in en_faces for y, z in en_new_faces if w <= y)

#rolls > 1 因为第一卷与面相同。 当滚动 > 1

#new_list find the sum of combos that happen twice such as (1,3) & (3,1)
new_list = [(x+z) for w,x,y,z in new_faces if w != y]

#even_list finds the sum of combos that happen once such as (1,1) or (2,2). Even though the combos only happen once, the sum may not be unique.
even_list = [(x+z) for w,x,y,z in new_faces if w == y]

这些列表是分开的,因为偶数列表组合的概率是 (1/(len(faces)**rolls)) 而 new_list 组合的概率是 (2/(len(faces)* *卷))

通过保持列表有序,我们可以保持它,以便数字的第一个 len(faces) 发生一次的概率和 new_faces 中剩余数字发生两次的概率无论有多少卷我们通过。

Here is how i’ve been keeping it in order:
for (x) in even_list:
    new_list.append(x) 
new_list = list(reversed(new_list))
rolls = rolls - 1

这引出了我的问题。

IIUC,您可以在遍历列表时使用 enumerate 来跟踪索引和值:

condenced_sums = []
condenced_probs = []

for i, x in enumerate(sums):
    if x not in condenced_sums:
        condenced_sums.append(x)
        condenced_probs.append(Probs[i])

您应该使用映射数据结构来收集总和:

from collections import OrderedDict

d = OrderedDict()

for s, p in zip(Sums, Probs):
    d[s] = d.get(s, 0) + p

Sums = [*d.keys()]
Probs = [*d.values()]