【问题标题】:Simplify this python code简化这个python代码
【发布时间】:2011-05-01 00:58:32
【问题描述】:

我编写了一个程序来检查我对纸上解决方案的想法是否正确(确实如此)。

任务:从 10 到 200 的所有数字相乘后有多少个零。

48,手动计算很简单。

我从来没有认真写过python,这就是我得到的:

mul = 1
for i in range(10, 200 + 1):
    mul *= i

string = str(mul)
string = string[::-1]
count = 0;
for c in str(string):
    if c == '0':
        count += 1
    else:
        break

print count
print mul

我敢打赌,用类似 python 的语言编写同样更优雅的代码是可能的。

ps:是的,这是作业,但不是我的 - 我只是帮助了一个人;-)

【问题讨论】:

    标签: python


    【解决方案1】:

    一个不涉及计算阶乘的简单实现(因此它适用于大数字,即 2000000!)(已编辑):

    fives = 0
    twos = 0
    for i in range(10, 201):
       while i % 5 == 0:
          fives = fives + 1
          i /= 5
       while i % 2 == 0:
          twos = twos + 1
          i /= 2
    print(min(fives, twos))
    

    【讨论】:

    • 它迭代地计算阶乘素数分解中的五和二的数量(所以 10! 将有 2 个五和 8 个二)。由于 5 * 2 = 10,并且没有其他素数可以乘以 10,因此分解中 10 的数量(即尾随零的数量)是素数中五的数量和二的数量中的最小值因式分解。五、二的数量比计算出的阶乘要小很多。
    • 虽然这个问题确实需要 10-200,但对于更大的数字来说,这绝对是一个更好的方法。对于较小的数字,实际上做乘法会更快(至少在我运行 timeit 测试时)。
    • 这是一个非常有趣的方法。我喜欢它。
    • 好吧,我检查这个只是因为它可读性强,并且具有良好的数学背景。
    【解决方案2】:
    import math
    
    answer = str(math.factorial(200) / math.factorial(9))
    count = len(answer) - len(answer.rstrip('0'))
    
    1. 导入数学库
    2. 计算 200 的 factorial 并去掉前 9 个数字
    3. 去掉右边的零并找出长度的差异

    【讨论】:

    • 目前最简洁的
    • reduce(operator.mul, xrange(10, 200 + 1)) 不会比阶乘 + 除法更有效吗?
    • @Brendan Long:感谢所有答案,但我会检查最优雅的一个;-P
    • 绝对 - 但我们会为了简单起见。如果您在函数式编程方面没有太多经验,我认为此解决方案将是最简单的解决方案之一。
    【解决方案3】:
    print sum(1 + (not i%25) + (not i%125) for i in xrange(10,201,5))
    

    【讨论】:

      【解决方案4】:
      import itertools
      mul = reduce(lambda x,y: x*y, range(10, 200+1))
      zeros = itertools.takewhile(lambda s: s == "0", reversed(str(mul)))
      print len(list(zeros))
      

      第二行计算乘积,第三行获取该数字中所有尾随零的迭代器,最后打印该零的数量。

      【讨论】:

      • 可以用operator.mul替换lambda x,y: x*y
      • 和range 和xrange (虽然在这种情况下是次要的)
      • @Brendan Long:因为我们总是从范围的开始到结束进行迭代 - xrange 根本不是开销吗?
      • @zerms:唯一的区别是range 预先创建了整个列表(并将其存储在内存中),而xrange 只返回对数字的迭代(它所要存储的只是当前的)。在这种情况下,内存和速度差异都可以忽略不计,但我想我会指出它,因为它是“pythonic”方式(Python 3 中的默认值)。
      • @Brendan Long:我知道其中的区别,但我一直认为 xrange 仅适用于我们不确定是否会迭代到最后的循环。
      【解决方案5】:
      len(re.search('0*$', str(reduce(lambda x, y: x*y, range(10, 200 + 1),1))).group(0))
      

      【讨论】:

      • 但如果您喜欢函数式编程、旁观者之眼等等,那就太棒了!
      • 我不会说这是非常实用的。在函数式编程中你看不到很多正则表达式。
      【解决方案6】:

      你是说零吗?否则什么是 null?

      一些数学不会让它更简单吗?

      200中有多少个5是len([x for x in range(5, 201, 5)]) = 40

      200中有多少个25是len([x for x in range(25, 201, 5) if x%25 == 0]) = 8

      200 中有多少个 125 是 len([x for x in range(120, 201, 5) if x%125 == 0]) = 1

      总共 5 秒 = 49

      200! = 5^49 * 2 ^49 *(其他不能被 2 或 5 整除的数)

      所以有 49 个零

      【讨论】:

      • 要清楚 - 它是 48,而不是 49 ;-) 我以类似的方式手动解决了它。当前的问题只是对如何在python中编写“蛮力”算法的好奇。
      • @zerkms:我猜你一定已经这样做了。傻我!
      【解决方案7】:
      mul = str(reduce(lambda x,y: x*y, xrange(10, 201)))
      count = len(mul) - len(mul.rstrip("0"))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-04-03
        • 2011-07-21
        • 1970-01-01
        • 2019-09-15
        • 1970-01-01
        • 2021-01-09
        • 2011-01-29
        • 2012-03-08
        相关资源
        最近更新 更多