【问题标题】:Count unique digits one liner (efficiently)计算唯一数字一行(有效)
【发布时间】:2012-05-25 10:06:27
【问题描述】:

我正在寻找一种方法来有效地计算唯一数字。

例如:给定整数623562,返回值为4

我目前的做法是,给定整数i,我使用len(set(str(i)))。 创建一个集合非常耗时。我要检查很多数字,所以我需要一种有效的方法。

另外,如果有人可以找到一种方法来遍历所有带有x 数字的数字而不使用 range()(和一个班轮......),我会很高兴的。使用range 时内存限制了我,因为创建了一个列表(我假设)。

【问题讨论】:

  • 创建一个集合很耗时 - 谁说的?
  • 当您说“很多数字”时,我们指的大概是多少?对于第二个问题,使用xrange()
  • 如果len(set(str(i))) 对你来说太慢了,那么我认为你不能通过手动迭代数字来更快地获得它。考虑使用 pypy 或 Cython。
  • 你想要高效的还是一个班轮?
  • 也许标题应该是 Count unique numbers one liner (efficient) 然后

标签: python


【解决方案1】:

sets 已针对此创作进行了优化。除非您想推出自己的十进制到字符串的转换(这需要不止一行),否则这是可行的方法。

range 仅在 Python 2.x 中分配内存。对于像 623562 这样的小数字,内存应该不是问题。对于较大的数字,请在 Python 2.x 中使用 xrange 或直接切换到 Python 3.x,其中 range 会及时生成数字。

【讨论】:

  • 谢谢,我使用的是 python 2.7,所以 xrange 确实有帮助,因为范围甚至可以是 9 位数字。然而,在高范围内,python 说 int 太大了,我开始怀疑是否有办法超越将它们视为字符串的数字。关于设置,不要忘记我的目标,我正在寻找任何方法来计算给定数字中的唯一数字,如果你有任何不包括十进制到字符串转换的方法,它仍然足够了。
  • 您可以使用插件获取xrange for large numbers。无意冒犯,但是您的要求(单行,Python,但不惜一切代价提高速度)似乎有些)困惑。如果性能确实是一个问题,那么您应该考虑编写一个优化的 C 程序来完全满足您的需求。这将不仅仅是一行,但为什么这很关键?
  • 这是一个项目的一部分,我需要它。我还有另一个列表大小问题:我需要对范围内的所有数字求和,每个数字的唯一数字的计数,所以我使用列表推导创建一个列表,然后对其求和。有没有办法在不创建列表的情况下即时汇总这些计数?给定 x(位数),我目前在做什么是: sum([len(set(str(i))) for i in xrange(10**(x-1),10**x)])
  • 您可以简单地丢失括号。这将使您的list comprehension 成为generator expression,它不需要预先存储内存。你的项目要求真的很奇怪。为什么你的客户坚持单线?如果是作业或代码高尔夫,你应该tag它。
【解决方案2】:

我很难相信len(set(str(num))) 对你来说还不够快。这是一个对随机非常大的数字进行 100,000 次 len(set(str())) 的测试:

% python -m timeit -s 'import random' 'for i in range(100000): \
  len(set(str(random.randint(199123212312399956789, 1000000099999999123091230000000))))'
10 loops, best of 3: 456 msec per loop

其中相当一部分时间只是生成随机数!如果你真的需要比这更快,我认为你应该考虑另一种语言。

【讨论】:

    【解决方案3】:

    这是一种避免每次都创建集合的方法。除了最后一行之外都是初始化代码,所以只发生一次:

    >>> from operator import or_
    >>> from collections import Counter
    >>> from functools import reduce
    >>> bits = {str(i):2**i for i in range(10)}
    >>> counts = [Counter(format(i,'b'))['1'] for i in range(2**10)]
    
    >>> counts[reduce(or_, (bits[c] for c in str(623562)))]
    4
    

    但是,它比简单、清晰、明显的len(set(str(i))) 慢了大约 3 倍。像往常一样,在 Python 中使事情变得更复杂或试图变得过于聪明都会反过来影响性能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-20
      • 1970-01-01
      • 2018-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-08
      • 1970-01-01
      相关资源
      最近更新 更多