繁体   English   中英

在python中获取具有唯一数字的数字的最快方法是什么?

[英]What is the quickest way to get a number with unique digits in python?

让我澄清:

获取两个数字之间所有唯一数字的每个数字的最快方法是什么。 例如,10,000 和 100,000。

一些明显的将是 12,345 或 23,456。 我试图找到一种方法来收集所有这些。

for i in xrange(LOW, HIGH):
  str_i = str(i)
  ...?

使用itertools.permutations

from itertools import permutations

result = [
    a * 10000 + b * 1000 + c * 100 + d * 10 + e
    for a, b, c, d, e in permutations(range(10), 5)
    if a != 0
]

我使用的事实是:

  • 10000100000之间的数字有 5 位或 6 位数字,但这里只有 6 位数字没有唯一数字,
  • itertools.permutations创建所有组合,具有所有排序(因此1234554321都将出现在结果中),具有给定的长度,
  • 您可以直接对整数序列进行排列(因此没有转换类型的开销),

编辑

感谢您接受我的回答,但这里是其他人的数据,比较了上述结果:

>>> from timeit import timeit
>>> stmt1 = '''
a = []
for i in xrange(10000, 100000):
    s = str(i)
    if len(set(s)) == len(s):
        a.append(s)
'''
>>> stmt2 = '''
result = [
    int(''.join(digits))
    for digits in permutations('0123456789', 5)
    if digits[0] != '0'
]
'''
>>> setup2 = 'from itertools import permutations'
>>> stmt3 = '''
result = [
    x for x in xrange(10000, 100000)
    if len(set(str(x))) == len(str(x))
]
'''
>>> stmt4 = '''
result = [
    a * 10000 + b * 1000 + c * 100 + d * 10 + e
    for a, b, c, d, e in permutations(range(10), 5)
    if a != 0
]
'''
>>> setup4 = setup2
>>> timeit(stmt1, number=100)
7.955858945846558
>>> timeit(stmt2, setup2, number=100)
1.879319190979004
>>> timeit(stmt3, number=100)
8.599710941314697
>>> timeit(stmt4, setup4, number=100)
0.7493319511413574

所以,总结一下:

  • 解决方案编号 1花了7.96 s
  • 解决方案编号 2(我原来的解决方案)花了1.88 s
  • 解决方案编号 3花了8.6 s
  • 解决方案编号 4(我更新的解决方案)花了0.75 s

最后一个解决方案看起来比其他人提出的解决方案快 10 倍左右。

注意:我的解决方案有一些我没有测量的导入。 我假设您的导入将发生一次,并且代码将执行多次。 如果不是这种情况,请根据您的需要调整测试。

编辑#2 :我添加了另一个解决方案,因为甚至不需要对字符串进行操作——它可以通过对实数进行排列来实现。 我敢打赌这可以加快速度。

这样做的廉价方法:

for i in xrange(LOW, HIGH):
    s = str(i)
    if len(set(s)) == len(s):
        # number has unique digits

这使用一set来收集唯一数字,然后检查是否有与总数字一样多的唯一数字。

列表理解在这里会起作用(从 nneonneo 窃取的逻辑):

[x for x in xrange(LOW,HIGH) if len(set(str(x)))==len(str(x))]

对于那些好奇的人来说,这是一个时间:

> python -m timeit '[x for x in xrange(10000,100000) if len(set(str(x)))==len(str(x))]'
10 loops, best of 3: 101 msec per loop

这是从头开始的答案:

def permute(L, max_len):
    allowed = L[:]
    results, seq = [], range(max_len)
    def helper(d):
        if d==0:
            results.append(''.join(seq))
        else:
            for i in xrange(len(L)):
                if allowed[i]:
                    allowed[i]=False
                    seq[d-1]=L[i]
                    helper(d-1)
                    allowed[i]=True
    helper(max_len)
    return results

A = permute(list("1234567890"), 5)
print A
print len(A)
print all(map(lambda a: len(set(a))==len(a), A))

也许可以通过使用允许元素的区间表示来进一步优化,尽管对于 n=10,我不确定它会有所作为。 我也可以将递归转换为循环,但在这种形式下它更优雅和清晰。

编辑:以下是各种解决方案的时间安排

  • 2.75808000565(我的解决方案)
  • 8.22729802132 (Sol 1)
  • 1.97218298912 (Sol 2)
  • 9.659760952 (Sol 3)
  • 0.841020822525 (Sol 4)
no_list=['115432', '555555', '1234567', '5467899', '3456789', '987654', '444444']
rep_list=[]
nonrep_list=[]
for no in no_list:
    u=[]
    for digit in no:
        # print(digit)
        if digit not in u:
            u.append(digit)
    # print(u)

    #iF REPEAT IS THERE
    if len(no) != len(u):
        # print(no)
        rep_list.append(no)
    #If repeatation is not there
    else:
        nonrep_list.append(no)
print('Numbers which have no repeatation are=',rep_list)
print('Numbers which have repeatation are=',nonrep_list)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM