繁体   English   中英

在python中检查一系列硬币投掷3的序列

[英]Checking a series of coin tosses for a sequence of 3 in python

我正在尝试创建一个翻转硬币的脚本,直到“head”连续翻转3次,或者“tails”连续翻转3次。

我的尝试是一段相当长的代码片段,它不能完成我想要它做的事情。 它只打印出“头”一次并永远循环:

import random

cointosses = []
total_count = 0

while total_count >= 0:
    tosses = random.randint(1,2)
    total_count += 1
    if tosses == 1:
        cointosses.append("heads")
    if tosses == 2:
        cointosses.append("tails")
    print(cointosses)
    seq_counter1 = 0
    seq_counter2 = 0
    total_seq = 0
    while total_seq <= 3:
        check1 = "heads"
        check2= "tails"
        for toss in cointosses:
            if toss == check1:
                seq_counter1 +=1 
                seq_counter2 = 0
                if seq_counter1 == 3:
                    total_seq = 3
                    break
            if toss == check2:
                seq_counter1 = 0
                seq_counter2 +=1
                if seq_counter2 == 3:
                    total_seq = 3
                    break

    if total_seq == 3:
        break

我确信有一些更简单的方法可以做到这一点,但我似乎无法弄明白。

你永远不会离开检查列表的while循环。 break语句只留下for -loop(设置total_seq = 3 ) - 你的while循环直到total_seq 大于 3 - > 无限循环

 while total_seq <= 3: # this is never been left because <= 3 check1 = "heads" # ^^ smaller equal check2= "tails" for toss in cointosses: if toss == check1: seq_counter1 +=1 seq_counter2 = 0 if seq_counter1 == 3: total_seq = 3 break # breaks out of the for but total_seq = 3 so in while if toss == check2: seq_counter1 = 0 seq_counter2 +=1 if seq_counter2 == 3: total_seq = 3 break # breaks out of the for but total_seq = 3 so in while 

您可以通过简单地添加到列表中,并检查,如果最后3个元素是相等的 ,而不是每次都检查全部列表简化代码很多

import random

def toss():
    """Return randomly 'heads' or 'tails'."""
    return "heads" if (random.randint(1,2) == 1) else "tails"

# need at least 3 tosses to finish
cointosses = []
for _ in range(3):
    cointosses.append(toss())
    print(cointosses)

# repeat until the set(..) of the last 3 elements contains exactly 1 item 
while not len(set(cointosses[-3:]))==1:
    cointosses.append(toss())
    print(cointosses)

print(f"It took {len(cointosses)} tosses to get 3 equal ones.")

输出2运行:

['tails']
['tails', 'tails']
['tails', 'tails', 'heads']
['tails', 'tails', 'heads', 'heads']
['tails', 'tails', 'heads', 'heads', 'heads']
It took 5 tosses to get 3 equal ones.

['tails']
['tails', 'tails']
['tails', 'tails', 'heads']
['tails', 'tails', 'heads', 'heads']
['tails', 'tails', 'heads', 'heads', 'tails']
['tails', 'tails', 'heads', 'heads', 'tails', 'heads']
['tails', 'tails', 'heads', 'heads', 'tails', 'heads', 'tails']
['tails', 'tails', 'heads', 'heads', 'tails', 'heads', 'tails', 'tails']
['tails', 'tails', 'heads', 'heads', 'tails', 'heads', 'tails', 'tails', 'heads']
['tails', 'tails', 'heads', 'heads', 'tails', 'heads', 'tails', 'tails', 'heads', 'heads']
['tails', 'tails', 'heads', 'heads', ... snipp ..., 'tails', 'heads', 'heads', 'tails']
['tails', 'tails', 'heads', 'heads', ... snipp ..., 'heads', 'heads', 'tails', 'tails']
['tails', 'tails', 'heads', 'heads', ... snipp ..., 'heads', 'tails', 'tails', 'tails']
It took 13 tosses to get 3 equal ones.

如果您不喜欢set()您还可以检查:

while not all(i == cointosses[-1] for i in cointosses[-3:-1]):
    # rest identical

数独:

这段代码存在一些问题:

1.此代码产生无限循环:

如果变量total_seq包含大于3的值,则内部while循环仅终止。 由于可能分配给它的唯一值是0和3 (根据您的代码) ,这个while循环将永远继续。

...
total_seq = 0 #<-----------------------
while total_seq <= 3:
    ...
    for toss in cointosses:
        if toss == check1:
            ...
            if seq_counter1 == 3:
                total_seq = 3 #<-----------------------
                break
        if toss == check2:
            ...
            if seq_counter2 == 3:
                total_seq = 3 #<-----------------------
                break
...

2.你只需在开始时翻一次,然后一遍又一遍地使用这个结果

random.randint(...)给你一个存储在cointosses列表中的值(这意味着:你只需要翻转一次硬币) 然而, 内部for循环假定您已经存储了大量的抛出列表。 如果它能找到3个连续的硬币翻转 ,它只将total_seq设置为3。

否则它将重复内部while循环并再次执行相同的操作而不添加新的coinflips (外部而永远不会再次到达)

tosses = random.randint(1,2)
...
if tosses == 1:
    cointosses.append("heads")
if tosses == 2:
    cointosses.append("tails")
...
    for toss in cointosses:
        ...
            if seq_counter1 == 3:
                total_seq = 3
                break
        ...
            if seq_counter2 == 3:
                total_seq = 3
                break
...

3.序列计数器seq_counter1和seq_counter2仅在前一个coinflip具有不同结果时才会重置。

由于你只需要翻转一次(如问题2所述) ,“之前的硬币翻转”总是你做的第一个。 这意味着你在开始时硬币翻转一次,并根据第一次翻转的结果将seq_counter1或seq_counter2增加到3。

...
seq_counter1 = 0
seq_counter2 = 0
...
while total_seq < 3:
    ...
        if toss == check1:
            seq_counter1 +=1
            seq_counter2 = 0
            ...
        if toss == check2:
            seq_counter1 = 0
            seq_counter2 +=1
            ...
...

通过删除内部while循环并简单地在外部循环中执行其代码,可以解决所有这三个问题:

import random
cointosses = []
total_count = 0
while total_count >= 0:
    tosses = random.randint(1,2)
    total_count += 1
    if tosses == 1:
        cointosses.append("heads")
    if tosses == 2:
        cointosses.append("tails")
    print(cointosses)
    seq_counter1 = 0
    seq_counter2 = 0
    total_seq = 0
    check1 = "heads"
    check2= "tails"
    for toss in cointosses:
        if toss == check1:
            seq_counter1 +=1
            seq_counter2 = 0
            if seq_counter1 == 3:
                total_seq = 3
                break
        if toss == check2:
            seq_counter1 = 0
            seq_counter2 +=1
            if seq_counter2 == 3:
                total_seq = 3
                break

    if total_seq == 3:
        break

这是因为条件total_seq == 3已经由外部循环中的最后一个if语句测试。

结论

但是,由于您构建了一个列表并一次又一次地迭代它,因此这段代码并不完整。 每次附加一个cointoss时,你都会迭代所有内容。 但是如果你考虑一下:你只需要检查新附加的元素是否创建了一个连续的行。

如果你想做到这一点,你应该只用一个循环(没有嵌套循环) :)

暂无
暂无

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

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