Nic*_*ler 5 python integer list significant-digits
说我有清单 [34523, 55, 65, 2]
获得[3,5,6,2]最有效数字的最有效方法是什么.如果可能的话,不改变每个改变str()?
sen*_*hin 13
假设您只处理正数,则可以将每个数字除以小于该数字的最大幂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]
Run Code Online (Sandbox Code Playgroud)
如果您使用的是Python 3,则可以使用整数除法运算符//:
>>> [x // (10**floor(log10(x))) for x in lst]
[3, 5, 6, 2]
Run Code Online (Sandbox Code Playgroud)
但是,我不知道这是否比转换为字符串和切片第一个字符更有效.(请注意,如果必须处理0到1之间的数字,则需要更复杂一些.)
>>> [int(str(x)[0]) for x in lst]
[3, 5, 6, 2]
Run Code Online (Sandbox Code Playgroud)
如果这是一个性能关键的代码片段,您应该测量两个选项,看看哪个更快.如果它不在一个性能关键的代码中,请使用最易读的代码.
我使用 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,
),
)
Run Code Online (Sandbox Code Playgroud)
如您所见,对于 中的数字range(1, 10_000_000),int(str(i)[0])比其他方法更快。我能得到的最接近的是使用一个简单的 while 循环:
def most_significant_while_floordiv(i):
while i >= 10:
i //= 10
return i
Run Code Online (Sandbox Code Playgroud)