Python 有没有更简洁/通灵的方法?(计算投币时最长的正面、反面)

Python 有没有更简洁/通灵的方法?(计算投币时最长的正面、反面),python,Python,计算200次抛硬币中最长的正面和反面序列。 我做到了这一点-有没有更好的方法在python中实现这一点?(没有太模糊) 看看是什么促使我玩的这可能是一条公理,任何代码都可以变得更简洁。不过你的看起来很像蟒蛇 事实上,反省一下,也许没有像这样简洁的公理。如果是“以简洁精确的表达为标志,没有浪费的文字”,如果“文字”是指代码文字而不是内存文字,那么单字程序就不能变得更简洁(除非它可能是“退出”程序) 如果它的意思是“具有非凡的规模和权力”,那么它似乎与简洁对立,除非我们将我们的定义仅限于权力。我不相

计算200次抛硬币中最长的正面和反面序列。
我做到了这一点-有没有更好的方法在python中实现这一点?(没有太模糊)


看看是什么促使我玩的

这可能是一条公理,任何代码都可以变得更简洁。不过你的看起来很像蟒蛇

事实上,反省一下,也许没有像这样简洁的公理。如果是“以简洁精确的表达为标志,没有浪费的文字”,如果“文字”是指代码文字而不是内存文字,那么单字程序就不能变得更简洁(除非它可能是“退出”程序)

如果它的意思是“具有非凡的规模和权力”,那么它似乎与简洁对立,除非我们将我们的定义仅限于权力。我不相信您的程序与先知预言完全相似,尽管您可以将其实现为特定先知预言的ascii画像。它看起来不像蛇,所以也有改进的余地

import random

def toss(n):
    '''
     ___     ____________
<<<((__O\   (__<>___<>__ \   ____
       \ \_(__<>___<>__)\O\_/O___>-<  hiss
        \O__<>___<>___<>)\___/

    '''
    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)
随机导入
def投掷(n):
'''
___     ____________

这不是真正的pythonic,而是折磨,但这里有一个简短的版本(具有无意义的1字符变量名,不少于!)


您可以使用
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)

另一个低效的解决方案:-)

正如您所注意到的,这是一种更为“解耦的”——
runlength
是一种完全通用的方法,用于确定任何iterable中不同散列项的最大运行长度(如果您在各种不同的上下文中需要这样的运行长度,则高度可重用),正如
makesequence
是一种完全通用的方法,可以在给定列表长度和每个随机数的选择数的情况下生成随机数列表。将这两个问题放在一起可能无法为给定的、高度特定的问题提供最佳的点解决方案,但会很接近,而且构建可重用的“构建块”小库将比仅通过完全专用的代码解决每个特定问题有更高的长期回报。

String scanning algorithm 如果你正在寻找一种快速算法,那么你可以使用我最近开发的一个面试问题的算法,该问题要求一个字符串中连续字母的最长字符串

使用
timeit
的1000次迭代的计时结果:

range: 2.670
xrange: 0.3268
while-loop: 0.255
psyco
import添加到文件中:

try:
    import psyco
    psyco.full()
except ImportError:
    pass


使用
psyco
和while循环进行1000次迭代时为0.011。因此,通过明智的微优化和导入
psyco
,代码运行速度快了250倍。

感谢上帝,其他人使用了
itertools
,而不是投票表决当前导致的字符串拆分和加入恐怖。对于真正大的num值,使用生成器可能比实际创建整个列表更好。@Emil:虽然我很欣赏你的建议,但我要指出1)它是一个包含
1
s和
0
s的列表;2) 中间列表将占用更多的内存。我不使用列表。不管怎样,我会选择这一款,因为这正是我一直在寻找的东西。尽管“应该有一种——最好只有一种——显而易见的方法可以做到这一点”,但我还是惊讶于出现了这么多不同的解决方案。谢谢大家,我需要一个openid,以便下次可以投票等等。干杯史蒂夫+1:非常清晰!我也喜欢亚历克斯的回答,这是非常有效的记忆,但需要更多的努力才能理解。好吧,我认为这给了我最大的正面或反面的顺序计数,对吗?谢谢,是的。很抱歉有点误读了这个问题,但很容易纠正。说真的,为什么要投票?我希望我能投两次反对票。“简单比复杂好。”谢谢Jed,这看起来更好,我需要更多地研究itertools来遵循这一点。许多感谢实际上是你对涉及
itertools
的问题的回答,让我了解了这个概念。我很高兴你反复敲鼓。你能用len(group)isntead of sum(1代表uu in group)吗?我今天在学习东西,尤其是我不知道的东西!谢谢你this@Emil:
group
是一个
itertools.\u grouper
对象,它没有
len
,替代方法是首先将其转换为
列表
。@abyx,学习itertools并明智地使用它是Python中实现高可伸缩性的关键秘密之一:除非您确信自己编写的代码没有人会特别关心,否则,使其可伸缩是一个很好的预防措施——而且一点也不复杂;那些以前忽视itertools并“被迫”查找它的“人”实际上是这里的大赢家,因为他们接触到了一个非常棒、非常实用的工具;见@Jed的评论@罗伯特,是的,将“流线化”提升一个档次来使用imap在这里也是很有可能的。如果你只寻找一组跑步,那一点效率都不低。看起来和Jed的差不多,上面我也喜欢,thanks@Steve:有区别。我一直保持函数内存的高效性,就像原始的(有问题的)一样,因此它可以用于非常大的
n
,而Jed和SilentGhost的解决方案可以创建大型中间数组。pythonic的意思是:以及
导入此
。有人可以做这个传说中的“数学”我很惊讶出现了这么多不同的解决方案,尽管“应该有一种——最好只有一种——显而易见的方法来做到这一点。”谢谢大家,我需要一个openid,以便下次可以投票等等。大家好,顺便说一句,您可能希望将这两个范围调用更改为xrange调用(当然是Python 2)。随着试验序列长度的增加,所有这些额外的列表创建开始增加。xrange版本的长度为2000,比range版本(Python 2.6)快10倍左右。@Ned:谢谢。如果我要这样做,我会使用while循环进行探索。也许我会
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)
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}
import random, re
s = ''.join(str(random.randrange(2)) for c in range(10))
print s
print max(re.findall(r'0+', s))
print max(re.findall(r'1+', s))

>>> 
0011100100
00
111
>>> 
import random, itertools

def toss(n):
    faces = (random.randrange(2) for i in range(n))
    longest = [0, 0]
    for face, seq in itertools.groupby(faces):
        longest[face] = max(longest[face], len(list(seq)))
    print "longest sequence heads %d, tails %d" % tuple(longest)
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())
def search_longest_substring(s):
    """
    >>> search_longest_substring('AABBBBCBBBBACCDDDDDDAAABBBBCBBBBACCDDDDDDDAAABBBBCBBBBACCDDDDDDA')
    (7, 'D')
    """
    def find_left(s, midc, mid, left):
        for j in range(mid-1, left-1, -1):
            if s[j] != midc:
                return j + 1
        return left
    def find_right(s, midc, mid, right):
        for k in range(mid+1, right):
            if s[k] != midc:
                return k
        return right
    i, longest = 0, (0, '')
    while i < len(s):
        c = s[i]
        j = find_left(s, c, i, i-longest[0])
        k = find_right(s, c, i, len(s))
        if k-j > longest[0]:
            longest = (k-j, c)
        i = k + longest[0]
    return longest

if __name__ == '__main__':
    import random
    heads_or_tails = "".join(["HT"[random.randrange(0, 2)] for _ in range(20)])
    print search_longest_substring(heads_or_tails)
    print heads_or_tails
def find_left(s, midc, mid, left):
    j = mid - 1
    while j >= 0:
        if s[j] != midc:
            return j + 1
        j -=  1
    return left
def find_right(s, midc, mid, right):
    k = mid+1
    while k < right:
        if s[k] != midc:
            return k
        k += 1
    return right
range: 2.670
xrange: 0.3268
while-loop: 0.255
try:
    import psyco
    psyco.full()
except ImportError:
    pass