从python中的数字(整数)中删除一个数字

时间:2017-10-28 16:35:15

标签: python string

对于所有指数,我需要删除该地方的数字。 整数a,将其转换为String,即S. 在遍历字符串长度后,

for i in range(len(S)):
    new =S[:i]+S[i+1:]

有没有更有效的方法从整数中删除数字?

3 个答案:

答案 0 :(得分:2)

更新:这似乎违反直觉,但基于字符串的解决方案快得多然后基于int。这里是我的代码和结果,在几秒钟内可以获得103位,226位和472位数字。我决定不在笔记本电脑上测试102139位数字:)

import timeit, math

digits = [100, 200, 500, 1_000, 2_000, 5_000, 10_000, 50_000, 100_000]

def print_str(n):
  s = str(n)
  for i in range(len(s)):
    #print(i)
    n2 = int(s[:i] + s[i+1:])


def print_int(a):
  p = 1
  while p <= a:
        n2 = a//p//10*p + a%p
        p *= 10

if __name__ == '__main__':
  number = 1
  for i in digits:
    n = 17**math.ceil(math.log(10**i, 17))
    str_ = timeit.timeit('print_str(n)', setup='from __main__ import print_str, n', number=number)
    int_ = timeit.timeit('print_int(n)', setup='from __main__ import print_int, n', number=number)
    print("{:8d}\t{:15.6f}\t{:15.6f}".format(len(str(n)), str_/number*1000, int_/number*1000))

结果(特定数字长度的毫秒数):

$ time python3 main.py
     101           0.169280        0.185082
     201           0.502591        0.537000
     501           3.917680        3.195815
    1001          13.768999       22.781801
    2001         114.404890      120.546628
    5001        1066.541904     1625.172070
   10002        8033.144731     8802.031382
   50001      937385.167088  1045865.986814
  100002     7800950.456252  8189620.010314

第一列 - 基于str的解决方案的位数 - 第二位 - 以毫秒为单位,第三位 - 基于int的位数。

但怎么可能?

可以理解,如果我们记住在Python中如何构造无穷大的整数。在引擎盖下,连接的15位或30位整数数组产生结果数。因此,当你划分这个数字时,你必须遍历整个数组并修改每一个数字。同时考虑到复杂性 - 有时你必须在更重要的数字上加或减,这会使过程变得复杂。

使用字符串时,只能将字节从一个地方复制到另一个地方。它是使用内部cpu指令进行的极快程序。

但是如果我们不需要转换为int呢?例如,我们想要打印一个数字,所以以字符串形式使用它会更好吗?它将如何进入过程?

此处&#39;结果 - 也以毫秒为单位显示

 $ time python3 main.py
     101           0.051510        0.124668
     201           0.091741        0.442547
     501           0.357862        2.562110
    1001           0.787016       15.229156
    2001           2.545076      111.917518
    5001           4.993472     1334.944235

UPD:更新版本的Bencharks:

$ time python3 main2.py

digits        str1        str2        int1        int2
   101       0.047       0.101       0.110       0.073
   201       0.091       0.315       0.380       0.145
   501       0.338       2.049       2.540       0.778
  1001       1.342      16.878      16.032       1.621
  2001       1.626      85.277      97.809       5.553
  5001       4.903    1039.889    1326.481      32.490
 10002      15.987    7856.753    9512.209     129.280
 20001      72.205   60363.860   68219.334     487.088

real    2m29.403s
user    2m27.902s
sys 0m0.577s

答案 1 :(得分:1)

你也可以不用字符串来做:

>>> a = 12345
>>> p = 1
>>> while p <= a:
        print a/p/10*p + a%p
        p *= 10

1234
1235
1245
1345
2345

答案 2 :(得分:1)

另一个产生整数的答案,比我的其他答案和OP的字符串解决方案要快得多:

>>> a = 12345

>>> digits = [0] + list(map(int, str(a)))
>>> p = 10**(len(digits) - 2)
>>> for x, y in zip(digits, digits[1:]):
        a += (x - y) * p
        p //= 10
        print(a)

2345
1345
1245
1235
1234

这是从2345到1345,将2替换为1,它通过减去2⋅1000并加1⋅1000来实现。或者简而言之,通过添加(1-2)⋅1000。然后通过添加(2-3)⋅100从1345到1245。等等。

基准测试结果,使用Eugene程序的修改版本:

digits        str1        str2        int1        int2
   101       0.085       0.255       0.376       0.157
   201       0.161       0.943       1.569       0.389
   501       0.514       9.180       9.932       0.983
  1001       0.699      30.544      39.796       2.218
  2001       1.402     203.429     291.006       8.435
  5001       4.852    2691.292    3983.420      50.616
 10002      16.080   21139.318   29114.274     197.343
 20001      54.884  167641.593  222848.841     789.182

str1是OP的字符串解决方案的时间,产生字符串。

str2是OP的字符串解决方案的时间,将字符串转换为整数 int1是我生成int的另一种解决方案 int2是我生成int的新解决方案。

OP的字符串解决方案总体上是最快的,这并不奇怪。它的运行时复杂度是数字的二次方。这是总输出大小,因此是最佳的。我的新解决方案也是二次方的,但进行计算当然比纯粹复制更有效。

为了生产整体,我的新解决方案是迄今为止最快的。我的旧版本和OP的版本具有立方体运行时间(OP显然是旧版本的1.4倍)。

基准程序(Eugene&#39;的修改版):

import timeit, math

digits = [100, 200, 500, 1_000, 2_000, 5_000, 10_000, 20_000]

def print_str_1(n):
  s = str(n)
  for i in range(len(s)):
    #print(i)
    n2 = s[:i] + s[i+1:]

def print_str_2(n):
  s = str(n)
  for i in range(len(s)):
    #print(i)
    n2 = int(s[:i] + s[i+1:])

def print_int_1(a):
  p = 1
  while p <= a:
        n2 = a//p//10*p + a%p
        p *= 10

def print_int_2(a):
    digits = [0] + list(map(int, str(a)))
    p = 10**(len(digits) - 2)
    for x, y in zip(digits, digits[1:]):
        a += (x - y) * p
        p //= 10
        #print(a)

if __name__ == '__main__':
  print(("{:>6}" + 4 * "{:>12}").format('digits', 'str1', 'str2', 'int1', 'int2'))
  number = 1
  for i in digits:
    n = 17**math.ceil(math.log(10**i, 17))
    str1 = timeit.timeit('print_str_1(n)', setup='from __main__ import print_str_1, n', number=number)
    str2 = timeit.timeit('print_str_2(n)', setup='from __main__ import print_str_2, n', number=number)
    int1 = timeit.timeit('print_int_1(n)', setup='from __main__ import print_int_1, n', number=number)
    int2 = timeit.timeit('print_int_2(n)', setup='from __main__ import print_int_2, n', number=number)
    print(("{:6d}" + 4 * "{:12.3f}").format(len(str(n)), *(x/number*1000 for x in (str1, str2, int1, int2))))