使用`str`是在Python中使用数字的正确习惯用法

oro*_*ome 7 python string indexing type-conversion digits

我理解在Python中使用数字的数字的一种方法是将数字转换为字符串,然后使用字符串方法将得到的"数字"分割成"数字"组.例如,假设我有一个功能prime,测试素性,我可以证实,一个整数ñ既是左右截去主要

all(prime(int(str(n)[:-i])) and prime(int(str(n)[i:])) for i in range(1, len(str(n))))
Run Code Online (Sandbox Code Playgroud)

此方法涉及首先将n转换为字符串,以便可以对其进行切片,并将该切片转换回整数,以便检查其原始性.也许这是我的静态类型语言的历史,或一些模糊的想法,字符串是"昂贵的",或经验与包含类似操作的内置功能的语言(如Mathematica的 IntegerDigitsFromDigits); 但是我想知道这是否是进行此类任务的正确方法.

在stings和数字之间来回转换是正确的 - 甚至是唯一的 - 用于访问Python中的数字的方法.有更有效的方法吗?

Blc*_*ght 6

在您的示例代码中,您可以使用divmod而不是字符串切片数字.divmod(x, y)返回元组x//y, x%y,对于您的数字的左右部分,这些y10**i正是您想要的.这不一定更像Pythonic,虽然它可能会更快一些.

sn = str(n)
all(prime(int(sn[:i])) and prime(int(sn[i:])) for i in range(1, len(sn))) # original
all(all(map(prime, divmod(n, 10**i))) for i in range(1, len(sn))) # variant using divmod
Run Code Online (Sandbox Code Playgroud)

我认为对于更一般的数字操作,使用str可能是非常明智的,因为对数字基数的幂进行大量数学运算可能比直接在字符串中的数字上做东西更难理解.

编写要读取的代码,除非它确实对性能敏感.


Jud*_*Jud 1

这一直是我的方法,而且效果很好,尽管我从未对速度进行过太多测试。当需要迭代数字的排列/组合时,它特别有效,因为您可以使用itertools包中的函数构建此类字符串。

当然还有其他方法涉及不太简单的数学运算,但除非速度绝对至关重要,否则我认为字符串方法是最 Pythonic 的。


例如,这是一种更数学化的方法,其中 a 和 b 从右侧开始索引(即个位为 0,十位为 1,等等):

def getSubdigits(n, a, b):
    n %= 10 ** a
    n //= 10 ** b
    return n
Run Code Online (Sandbox Code Playgroud)

为了使用与字符串切片相同的索引,您需要首先找到数字总数,并且该函数变为:

def getSubdigits2(n, a, b):
    l = int(math.ceil(math.log10(n)))
    n %= 10 ** (l - a)
    n //= 10 ** (l - b)
    return n
Run Code Online (Sandbox Code Playgroud)

和字符串切片等效:

def subDigits3(n, a, b):
    return int(str(n)[a:n])
Run Code Online (Sandbox Code Playgroud)

这是计时结果:

  • subDigits: 0.293327726114
  • subDigits2: 0.850861833337
  • subDigits3: 0.990543234267

我从这个结果中得出的结论是,切片方法很好,除非您真的关心速度,在这种情况下,您需要使用第一种方法并考虑另一个方向的索引。