创建一个随机列表并计算6个字母的长度

2024-06-25 23:27:58 发布

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

我正在尝试建立一个程序,它将创建一个随机的正反面列表(“H”,“T”),然后计算“H”或“T”重复6次的次数。 我想我已经找到了随机列表,当我独立运行它时,它工作得很好。 但是说到计数,我不知道如何让python检测列表中6个相同字母的序列

for x in range(0, len(coin_list)-1):
    if coin_list[x] == coin_list[x+1] and coin_list[x] == coin_list[x+2] and \
    coin_list[x] == coin_list[x+3] and coin_list[x] == coin_list[x+4] and \
    coin_list[x] == coin_list[x+5]:
       streak_counter+=1
    else:
        continue

    if streak_counter ==6: 
        numberOfStreaks+=1
        streak_counter=0
    else: 
        continue

首先,该块检查列表coin_list中的每个值,并检查其后面的所有5个值是否与第一个值相同。如果是,则条纹计数器变量增加1。然后程序检查条纹计数器变量是否等于6,如果等于6,则条纹数变量增加1,并且条纹计数器重置为0

当我运行这个程序时,我没有得到预期的结果。程序总是返回numberOfStreaks等于0,因此条纹百分比为0%

我不知道我哪里出了问题。任何帮助都将不胜感激

import random
numberOfStreaks = 0


for experimentNumber in range(10000):
    # Code that creates a list of 100 'heads' or 'tails' values.
    for i in range(100):
        coin_list=[]
        random_num=random.randint(0, 1)
        if random_num == 1:
            coin_list.append('H')
        elif random_num == 0:
            coin_list.append('T')

    # Code that checks if there is a streak of 6 heads or tails in a row.
    for x in range(0, len(coin_list)-1):
        if coin_list[x] == coin_list[x+1] and coin_list[x] == coin_list[x+2] and \
        coin_list[x] == coin_list[x+3] and coin_list[x] == coin_list[x+4] and \
        coin_list[x] == coin_list[x+5]:
           streak_counter+=1
        else:
            continue

        if streak_counter ==6: 
            numberOfStreaks+=1
            streak_counter=0
        else: 
            continue


print(numberOfStreaks)
print('Chance of streak: %s%%' % (numberOfStreaks / 100))

Tags: andin程序列表forifcounterrange
3条回答

使用zip形成条纹并计算只有一个值的条纹:

from random import choice
from itertools import islice

flipCount = 20
streakSize = 6

coinList    = [choice("HT") for _ in range(flipCount)]
allHeads    = tuple("H",)*streakSize
allTails    = tuple("T",)*streakSize
streakCount = sum( s==allHeads or s==allTails
                   for s in zip(*(islice(coinList,i) for i in range(streakSize))))

输出:

print("".join(coinList))
print(streakCount)

# HHHHTTHHHHHHHTTHTHHH
# 2

1)如前所述,当streak_counter == 1时,您应该增加序列计数,因为当您检测到条纹时,您将其增加1。你可能会得到0,因为连续11次的几率要低得多

2)正如Błotosmętek所说,只制作一个字符串(str1 = ''.join(coint_list))然后使用字符串计数方法(str1.count('HHHHHH'))会更容易。如果要计算所有6次长度的运行(例如HHHHHHH=2次运行),请仔细阅读answers here.

更新:我做了一些测试,发现链接答案中的regex方法对于所有6次运行都要快得多。这是我使用的测试脚本

from random import randint as randi
import re
import timeit


# Create test list
longg = ['H' if randi(0,1) == 1 else 'T' for i in range(10000)]
longg = ''.join(longg)


def regVer(s):
    matches = re.finditer(r'(?=(H{6}|T{6}))',s)
    return len(list(matches))

def listVer(s):
    n = 6
    li = [s[i:i+n] for i in range(len(s)-n+1)]
    count = 0
    for i in li:
        if i == 'H'*6 or i == 'T'*6:
            count += 1
    return count

print('regCount: {}'.format(regVer(longg)))
print('Time elapsed: {}'.format(timeit.timeit('regVer(longg)', number=100, globals=globals())))
print('listCount: {}'.format(listVer(longg)))
print('Time elapsed: {}'.format(timeit.timeit('listVer(longg)', number=100, globals=globals())))

它给出了以下输出:

regCount: 356
Time elapsed: 0.070616307
listCount: 356
Time elapsed: 0.281572281

也许我只是不知道该怎么做

当前实现(生成硬币列表)有什么问题

在生成列表的代码中,为列表中的每个条目创建一个空列表

for i in range(100):
    coin_list=[]   # <  here you create an empty list
    random_num=random.randint(0, 1)
    if random_num == 1:
        coin_list.append('H')
    elif random_num == 0:
        coin_list.append('T')

检查硬币清单的长度:

len(coin_list)

output: 1

修复它的想法

可以通过在循环外部定义列表来解决此问题:

coin_list=[]
for i in range(100):

    random_num=random.randint(0, 1)
    if random_num == 1:
        coin_list.append('H')
    elif random_num == 0:
        coin_list.append('T')

由于您正在使用random,因此可以查看random.choice

coin_list = []
coins = ['H', 'T']
for i in range(100):
    coin_list.append(random.choice(coins))

在这两种情况下,列表的长度都是100

条纹计数有什么问题

接下来,streak_counter在被引用之前没有定义,因此应该定义它:

streak_counter = 0

为检查条纹而写入的循环将遇到以下错误:

IndexError: list index out of range

这是因为您允许x从0到列表的长度-1,然后使用x+2,3,4,5访问列表项。当循环到达列表后面的第四个项目时,它将尝试访问列表之外的项目,从而导致错误

for x in range(0, len(coin_list)-1):
    if coin_list[x] == coin_list[x+1] and coin_list[x] == coin_list[x+2] and \
    coin_list[x] == coin_list[x+3] and coin_list[x] == coin_list[x+4] and \
    coin_list[x] == coin_list[x+5]:  # <   here you are accessing x+5
       streak_counter+=1
    else:
        continue

    if streak_counter ==6: 
        numberOfStreaks+=1
        streak_counter=0
    else: 
        continue

解决方法是让x从0运行到len(list)-5,这将允许循环完成。 但是,检查条纹的方式有点奇怪:

for x in range(0, len(coin_list)-5):
    print(x)
    if coin_list[x] == coin_list[x+1] and coin_list[x] == coin_list[x+2] and \
    coin_list[x] == coin_list[x+3] and coin_list[x] == coin_list[x+4] and \
    coin_list[x] == coin_list[x+5]:
        streak_counter+=1
    else:
        continue

if语句检查列表中是否有六个连续的、相同的条目。如果是这种情况,则增加streak_counter

接下来,检查streak_counter是否为6,然后将其计为一条条纹并增加numberOfStreaks

if streak_counter ==6: 
    numberOfStreaks+=1
    streak_counter=0
else: 
    continue

这里的问题是,对于streak_计数器为6,必须满足if coin_list[x] == ...条件六次。因此,您需要至少11个连续的相同值来注册6个条纹

试图修复它

现在,如何解决这个问题,我想取决于你如何计算条纹:一个7个头的序列是一个7的条纹,还是两个6的条纹

对于前一种情况,您可以这样做:

s = ''.join(coin_list) # convert everything to string

tails_streaks = []
heads_streaks = []

for tails in s.split('H'): # remove all heads and check if what remains is at least 6 long
    if len(tails) >=6:
        tails_streaks.append(len(tails))

for heads in s.split('T'): # ditto for tails
    if len(heads) >=6:
        heads_streaks.append(len(heads))

如果要计算六个连续相同结果的所有出现次数(这意味着要将一枚硬币数数多次):

tails_sixes = []
heads_sixes = []

for tails in s.split('H'):
    if len(tails) >=6:
        tails_sixes += 1 + len(tails) - 6 

for heads in s.split('T'):
    if len(heads) >=6:
        heads_sixes += 1 + len(tails) - 6

相关问题 更多 >