在Python中获取最高有效数字

8

假设我有一个列表[34523, 55, 65, 2]

如何高效地获取[3,5,6,2],即每个数字的最高有效位?如果可能的话,不要使用str()函数转换成字符串。


如果你只有整数,请看一下这个答案。这是你问题的C语言版本。 - memoselyk
2个回答

17
假设你只处理正数,那么可以将每个数除以比它小的最大的10的幂,然后取结果的下限。
>>> from math import log10, floor
>>> lst = [34523, 55, 65, 2]
>>> [floor(x / (10**floor(log10(x)))) for x in lst]
[3, 5, 6, 2]

如果您使用的是Python 3,那么您可以使用整数除法运算符//来代替向下取整结果:

>>> [x // (10**floor(log10(x))) for x in lst]
[3, 5, 6, 2]

然而,我不知道这是否比将其转换为字符串并切片第一个字符更有效。 (请注意,如果您必须处理介于0和1之间的数字,则需要更复杂的处理方式。)

>>> [int(str(x)[0]) for x in lst]
[3, 5, 6, 2]

如果这段代码是性能关键的部分,你应该测量这两个选项并查看哪一个更快。如果它不是性能关键的部分,请使用对你来说最易读的选项。


该死,你比我先完成了。 - R Nar
还可以考虑使用除以十的循环,以防log和floor函数代价较高。 - Filip Haglund

8

我使用Python 3.6.1进行了一些计时:

from timeit import timeit

from math import *


lst = list(range(1, 10_000_000))


# 3.6043569352230804 seconds
def most_significant_str(i):
    return int(str(i)[0])


# 3.7258850016013865 seconds
def most_significant_while_floordiv(i):
    while i >= 10:
        i //= 10
    return i


# 4.515933519736952 seconds
def most_significant_times_floordiv(i):
    n = 10
    while i > n:
        n *= 10
    return i // (n//10)


# 4.661690454738387 seconds
def most_significant_log10_floordiv(i):
    return i // (10 ** (log10(i) // 1))


# 4.961193803243334 seconds
def most_significant_int_log(i):
    return i // (10 ** int(log10(i)))


# 5.722346990002692 seconds
def most_significant_floor_log10(i):
    return i // (10 ** floor(log10(i)))


for f in (
    'most_significant_str',
    'most_significant_while_floordiv',
    'most_significant_times_floordiv',
    'most_significant_log10_floordiv',
    'most_significant_int_log',
    'most_significant_floor_log10',
):
    print(
        f,
        timeit(
            f"""
for i in lst:
    {f}(i)
            """,
            globals=globals(),
            number=1,
        ),
    )

从下面的数据可以看出,对于range(1, 10_000_000)中的数字,使用int(str(i)[0])比其他方法更快。我能够找到的最接近的方法是使用简单的while循环:

def most_significant_while_floordiv(i):
    while i >= 10:
        i //= 10
    return i

1
所以,简单胜出。 - Abhijit Sarkar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接