简体   繁体   English

如何将列表中后面的元素组合到前面的元素,同时保持列表在后面的元素之前的顺序?

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

Long story short, I'm rolling unfair dice and trying to find the probability of any given sum after x number of rolls.长话短说,我正在掷不公平的骰子,并试图在掷 x 次后找到任何给定总和的概率。 In practice there are hundreds of faces and hundreds of rolls, so I can't simply find all possible combinations, then find the probability, do to list size and memory restrictions.实践中有数百张脸和数百张卷,所以我不能简单地找到所有可能的组合,然后找到概率,做列表大小和 memory 限制。

I'm working around this problem by finding all the possible combinations and their probability of occurring 1 roll at a time.我正在通过查找所有可能的组合及其一次出现 1 卷的概率来解决这个问题。 After I find all the possible combinations and the probability of each combo I need to condense it by combining the probabilities of combinations with the same sum.在我找到所有可能的组合和每个组合的概率后,我需要通过组合具有相同总和的组合概率来压缩它。

Think of the combos (1,3) and (2,2) both are unique combos, but they both have a sum of 4 and if the probability of (1,3) occurring is 3/6 and the probability of (2,2) occurring is 1/6 the probability of combos with the sum of 4 is 4/6.想想组合 (1,3) 和 (2,2) 都是独特的组合,但它们的总和都是 4,如果 (1,3) 发生的概率是 3/6 而 (2, 2) 发生是1/6 总和为4 的连击概率是4/6。

Hopefully I don't need to go into the details about why this works and the math behind it, but if more information is needed, please let me know.希望我不需要 go 详细了解为什么这有效以及背后的数学原理,但如果需要更多信息,请告诉我。

I've got it to the point that I have a list containing the sum of one of each possible combinations after a roll as well as a congruent list containing the probabilities of these sums.我已经知道我有一个列表,其中包含滚动后每个可能组合之一的总和,以及一个包含这些总和概率的一致列表。

For our example it's something like this:对于我们的示例,它是这样的:

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] 

In our real example, the numbers don't and can't have a common denominator and are long decimals, but I'm using these numbers to show what I'm looking for.在我们的真实示例中,数字没有也不能有公分母并且是长小数,但我使用这些数字来显示我要查找的内容。

Order is important.顺序很重要。 I can remove the dupe sums from the sums list and maintain the order I need by using:我可以从总和列表中删除重复的总和并使用以下方法维护我需要的顺序:

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

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

My problem is that the corresponding probability doesn't just go away, and the probability for the first occurrence and any duplicate occurrences are not the same.我的问题是相应的概率不只是 go ,而且第一次出现的概率和任何重复出现的概率都不一样。 To make sure the probabilities of each sum stays accurate, before I remove the duplicate occurrences' probability, I need to add it to the original occurrence's probability.为了确保每个总和的概率保持准确,在删除重复出现的概率之前,我需要将其添加到原始出现的概率中。 Ideally, the condensed prob will look like this:理想情况下,浓缩概率将如下所示:

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

I was thinking that maybe I could zip the lists together and get something like:我在想,也许我可以 zip 将列表放在一起并得到类似的东西:

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

Then maybe use an If else statement inside a list comprehension statement, but I'm still really new to this and haven't been able to think of a way to make this work.然后也许在列表理解语句中使用 If else 语句,但我对此仍然很陌生,还没有想出一种方法来完成这项工作。

As another note because I'm not sure if it will make a difference, any sum might occur several times, not just twice.另外请注意,因为我不确定它是否会有所作为,任何总和都可能出现多次,而不仅仅是两次。

Any help is appreciated, even if it's simply a better way to ask the question.感谢您提供任何帮助,即使这只是提出问题的更好方式。

Thanks!谢谢!

edit:编辑:

I thought it might be more useful to give a little more background as to why I need to maintain the order.我认为就为什么我需要维护订单提供更多背景知识可能更有用。 Here is what I have so far:这是我到目前为止所拥有的:

assuming faces = [1,2,3] #in reality this this is a random length list with random values new_faces = faces rolls = random number prob = [.5,.333333, .1666666] #this is a congruent list of random probabilities.假设 faces = [1,2,3] #in reality 这是一个随机长度的列表,带有随机值 new_faces = faces rolls = random number prob = [.5,.333333, .1666666] #this is a congruent list of random概率。 new_prob = prob 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) 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 because the first roll is the same as faces. #rolls > 1 因为第一卷与面相同。 While 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]

these lists are separated because the probability of even list combos are (1/(len(faces)**rolls)) and the probability of new_list combos are (2/(len(faces)**rolls))这些列表是分开的,因为偶数列表组合的概率是 (1/(len(faces)**rolls)) 而 new_list 组合的概率是 (2/(len(faces)**rolls))

By keeping the lists ordered, we can keep it so that the probability of the first len(faces) of numbers happen once and the probability of the remaining numbers in new_faces happen twice no matter how many rolls we go through.通过保持列表有序,我们可以保持它,以便数字的第一个 len(faces) 发生一次的概率和 new_faces 中剩余数字发生两次的概率,无论我们 go 通过了多少次。

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

And that leads us to my question.这引出了我的问题。

You should use a mapping data structure to collect the sums:您应该使用映射数据结构来收集总和:

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()]

IIUC, you can use enumerate while iterating over the list to keep track of the index and value: 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])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM