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

2024-05-02 10:45:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试创建一个脚本来翻转硬币,直到“头”连续翻转3次,或者“尾”连续翻转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

我肯定有更简单的方法,但我似乎想不出来。你知道吗


Tags: ifcountrandomseqtotalheadsbreakappend
2条回答

永远不要离开检查列表的while循环。break语句只留下for循环(设置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。你只需要在开始的时候翻动一次,然后一遍又一遍地使用这个结果

你知道吗随机.randint(…)给你一个值,这个值存储在cointhows列表中(意思是:你只掷硬币一次)。内部for循环假定列表中已经存储了大量抛出。如果能找到3个连续的coinflips,它只会将total_seq设置为3。你知道吗

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

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
...

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

由于您只需要进行一次coinflip(如问题2中所讨论的),所以“上一次coinflip”总是您进行的第一次coinflip。 这意味着您在开始时coinflip一次,并根据第一次翻转的结果将seq\u counter1或seq\u 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循环并在外部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语句进行了测试。你知道吗

结论

然而,这段代码并不是很好,因为您构建了一个列表并反复迭代它。 每次追加一个cointost时,您都在迭代所有内容。但是如果您仔细想想:您只需要检查新附加的元素是否创建了一个连续的行。你知道吗

如果要正确执行此操作,应该只使用一个循环(没有嵌套循环):)

相关问题 更多 >