有没有更简洁/更Pythonic的方式来做这个?(统计硬币翻转中最长的一串正反面)

11 投票
9 回答
1080 浏览
提问于 2025-04-15 15:44

计算在200次抛硬币中,最长的连续正面和反面序列。
我这样做了——在Python中有没有更聪明的方法?(希望不要太复杂难懂)

import random

def toss(n):
    count = [0,0]
    longest = [0,0]
    for i in xrange(n):
        coinface = random.randrange(2)
        count[coinface] += 1
        count[not coinface] = 0

        if count[coinface] > longest[coinface]:
            longest[coinface] = count[coinface]      
        #print coinface, count, longest  

    print "longest sequence heads %d, tails %d" %tuple(longest)

if __name__ == '__main__':
    toss(200)

可以看看这个链接,它让我开始这个练习的。

9 个回答

7

你可以使用 itertools,这是一种更符合Python风格的方法来实现这个功能:

def toss(n):
    rolls = [random.randrange(2) for i in xrange(n)]
    maximums = [0, 0]
    for which, grp in itertools.groupby(rolls):
        maximums[which] = max(len(list(grp)), maximums[which])

    print "Longest sequence of heads %d, tails %d" % tuple(maximums)
11
import collections, itertools, random

def makesequence(choices=2, length=200):
  return [random.randrange(choices) for _ in itertools.repeat(None, length)]

def runlengths(sequence):
  runlength_by_item = collections.defaultdict(set)
  for key, group in itertools.groupby(sequence):
    runlength_by_item[key].add(sum(1 for _ in group))
  return dict((k, max(v)) for k, v in runlength_by_item.items())

你会发现,这种方式更加“解耦”了——runlengths 是一种通用的方法,可以用来计算任何可迭代对象中不同可哈希项的最大连续长度(如果你在不同的场合需要这样的连续长度,这个方法非常好用)。而 makesequence 则是一个通用的方法,可以根据列表的长度和每个随机数的选择数量,生成随机数列表。把这两个方法结合起来,可能并不能完美解决某个特定的问题,但它会非常接近。而且,建立你自己的可重用“构建块”库,长期来看会比每次都用专门的代码来解决特定问题要更有价值。

11
def coins(num):
    lst = [random.randrange(2) for i in range(num)]
    lst = [(i, len(list(j))) for i, j in itertools.groupby(lst)]
    tails = max(j for i, j in lst if i)
    heads = max(j for i, j in lst if not i)
    return {1: tails, 0: heads}

当然可以!请把你想要翻译的内容发给我,我会帮你把它变得简单易懂。

撰写回答