在 Python 中查找数字的所有因数的最有效方法是啥?
Posted
技术标签:
【中文标题】在 Python 中查找数字的所有因数的最有效方法是啥?【英文标题】:What is the most efficient way of finding all the factors of a number in Python?在 Python 中查找数字的所有因数的最有效方法是什么? 【发布时间】:2011-10-11 15:03:12 【问题描述】:有人可以向我解释一种在 Python (2.7) 中找到数字的所有因数的有效方法吗?
我可以创建一个算法来执行此操作,但我认为它的编码很差,并且需要很长时间才能生成大量结果。
【问题讨论】:
我不懂python。但是这个页面可能对你有用en.wikipedia.org/wiki/Integer_factorization 使用primefac
怎么样? pypi.python.org/pypi/primefac
@Zubo primefac
似乎不适用于 Python 3。至少,不是在 3.9.4 上。
【参考方案1】:
from functools import reduce
def factors(n):
return set(reduce(list.__add__,
([i, n//i] for i in range(1, int(n**0.5) + 1) if n % i == 0)))
这将很快返回数字n
的所有因子。
为什么以平方根为上限?
sqrt(x) * sqrt(x) = x
。因此,如果这两个因素相同,它们都是平方根。如果你让一个因素变大,你必须让另一个因素变小。这意味着两者之一将始终小于或等于sqrt(x)
,因此您只需搜索到该点即可找到两个匹配因子之一。然后您可以使用x / fac1
获取fac2
。
reduce(list.__add__, ...)
正在提取[fac1, fac2]
的小列表并将它们组合成一个长列表。
[i, n/i] for i in range(1, int(sqrt(n)) + 1) if n % i == 0
返回一对因子,如果您将 n
除以较小的因子时的余数为零(它也不需要检查较大的因子;它只需将 n
除以较小的。)
外部的set(...)
正在消除重复项,这仅适用于完美的正方形。对于n = 4
,这将返回2
两次,所以set
删除其中一个。
【讨论】:
我从计算机上的算法列表中复制粘贴了这个,我所做的只是封装了sqrt
——这可能是在人们真正考虑支持 Python 3 之前。我认为该站点我通过对__iadd__
进行了尝试,它更快。不过,我似乎记得 x**0.5
在某些时候比 sqrt(x)
快——而且这样更万无一失。
如果我使用 if not n % i
而不是 if n % i == 0
,似乎执行速度快 15%
@sthzg 我们希望它返回一个整数,而不是浮点数,并且在 Python 3 上 /
将返回一个浮点数,即使两个参数都是整数并且它们完全可整除,即 4 / 2 == 2.0
不是2
.
我知道这是一个老问题,但在 Python 3.x 中,您需要添加 from functools import reduce
才能完成这项工作。
@unseen_rider:这听起来不对。你能提供任何东西来备份它吗?【参考方案2】:
@agf 提出的解决方案很棒,但是通过检查奇偶校验可以使任意 奇数 数的运行时间缩短约 50%。由于奇数的因数本身总是奇数,所以在处理奇数时不必检查这些。
我刚刚开始自己解决Project Euler 难题。在某些问题中,会在两个嵌套的for
循环内调用除数检查,因此该函数的性能至关重要。
将这一事实与 agf 的出色解决方案相结合,我最终得到了这个函数:
from functools import reduce
from math import sqrt
def factors(n):
step = 2 if n%2 else 1
return set(reduce(list.__add__,
([i, n//i] for i in range(1, int(sqrt(n))+1, step) if n % i == 0)))
但是,对于较小的数字(~
我进行了一些测试以检查速度。下面是使用的代码。为了生成不同的图,我相应地更改了X = range(1,100,1)
。
import timeit
from math import sqrt
from matplotlib.pyplot import plot, legend, show
def factors_1(n):
step = 2 if n%2 else 1
return set(reduce(list.__add__,
([i, n//i] for i in range(1, int(sqrt(n))+1, step) if n % i == 0)))
def factors_2(n):
return set(reduce(list.__add__,
([i, n//i] for i in range(1, int(sqrt(n)) + 1) if n % i == 0)))
X = range(1,100000,1000)
Y = []
for i in X:
f_1 = timeit.timeit('factors_1()'.format(i), setup='from __main__ import factors_1', number=10000)
f_2 = timeit.timeit('factors_2()'.format(i), setup='from __main__ import factors_2', number=10000)
Y.append(f_1/f_2)
plot(X,Y, label='Running time with/without parity check')
legend()
show()
X = 范围(1,100,1)
这里没有显着差异,但是数字越大,优势就很明显了:
X = range(1,100000,1000)(仅奇数)
X = range(2,100000,100)(仅限偶数)
X = range(1,100000,1001)(交替奇偶校验)
【讨论】:
【参考方案3】:agf 的回答真的很酷。我想看看我是否可以重写它以避免使用reduce()
。这是我想出的:
import itertools
flatten_iter = itertools.chain.from_iterable
def factors(n):
return set(flatten_iter((i, n//i)
for i in range(1, int(n**0.5)+1) if n % i == 0))
我还尝试了一个使用棘手的生成器函数的版本:
def factors(n):
return set(x for tup in ([i, n//i]
for i in range(1, int(n**0.5)+1) if n % i == 0) for x in tup)
我通过计算来计时:
start = 10000000
end = start + 40000
for n in range(start, end):
factors(n)
我跑了一次让Python编译,然后在time(1)命令下跑了3次,保持最佳时间。
减少版本:11.58 秒 itertools 版本:11.49 秒 棘手版:11.12 秒请注意,itertools 版本正在构建一个元组并将其传递给 flatten_iter()。如果我更改代码来构建一个列表,它会稍微变慢:
iterools(列表)版本:11.62 秒我相信棘手的生成器函数版本是 Python 中最快的版本。但它并没有比 reduce 版本快多少,根据我的测量大约快 4%。
【讨论】:
你可以简化“棘手的版本”(删除不必要的for tup in
):factors = lambda n: f for i in range(1, int(n**0.5)+1) if n % i == 0 for f in [i, n//i]
【参考方案4】:
SymPy 中有一个行业强度的算法,称为factorint:
>>> from sympy import factorint
>>> factorint(2**70 + 3**80)
5: 2,
41: 1,
101: 1,
181: 1,
821: 1,
1597: 1,
5393: 1,
27188665321L: 1,
41030818561L: 1
这花了不到一分钟的时间。它在多种方法之间切换。请参阅上面链接的文档。
鉴于所有主要因素,所有其他因素都可以轻松构建。
请注意,即使允许接受的答案运行足够长的时间(即永恒)以分解上述数字,对于一些大数字它也会失败,例如以下示例。这是由于草率的int(n**0.5)
。比如n = 10000000000000079**2
,我们有
>>> int(n**0.5)
10000000000000078L
由于10000000000000079 is a prime,接受答案的算法永远不会找到这个因素。请注意,这不仅仅是一个接一个。对于更大的数字,它将关闭更多。因此,最好避免在此类算法中使用浮点数。
【讨论】:
它没有找到所有除数,而只有主要因素,所以它不是真正的答案。您应该展示如何构建所有其他因素,而不仅仅是说它很容易!顺便说一句,sympy.divisors 可能更适合回答这个问题。 并注意 sympy.divisors 并不比公认的解决方案快多少。 @ColinPitrat:我有点怀疑sympy.divisors
并没有快多少,尤其是对于除数很少的数字。有任何基准吗?
@Ry 一年前我写这篇评论时做过一个。写一篇需要 2 分钟,所以请随时仔细检查。
@ColinPitrat:检查。正如预期的那样,接受的答案与sympy.divisors
100,000 的速度大致相同,而更高的速度则更慢(当速度实际上很重要时)。 (当然,sympy.divisors
适用于像 10000000000000079**2
这样的数字。)【参考方案5】:
这是@agf 解决方案的替代方案,它以更 Python 的风格实现相同的算法:
def factors(n):
return set(
factor for i in range(1, int(n**0.5) + 1) if n % i == 0
for factor in (i, n//i)
)
此解决方案在 Python 2 和 Python 3 中均适用,无需导入,并且更具可读性。我没有测试过这种方法的性能,但渐近地应该是相同的,如果性能是一个严重的问题,那么这两种解决方案都不是最优的。
【讨论】:
【参考方案6】:agf 回答的另一种方法:
def factors(n):
result = set()
for i in range(1, int(n ** 0.5) + 1):
div, mod = divmod(n, i)
if mod == 0:
result |= i, div
return result
【讨论】:
你能解释一下div、mod部分吗? divmod(x, y) 返回 ((x-x%y)/y, x%y),即除法的商和余数。 这不能很好地处理重复因素 - 例如尝试 81。 你的答案更清楚,所以我能够理解它足以误解。我在考虑素因数分解,您想在其中调用多个 3。这应该没问题,因为这是 OP 要求的。 我把所有东西都堆成一行,因为 agf 的回答就是这样做的。我很想看看reduce()
是否明显更快,所以除了reduce()
部分之外,我几乎都按照agf 的方式做了。为了可读性,最好看到像 is_even(n)
这样的函数调用,而不是像 n % 2 == 0
这样的表达式。【参考方案7】:
对于 n 最多 10**16(甚至可能更多),这是一个快速的纯 Python 3.6 解决方案,
from itertools import compress
def primes(n):
""" Returns a list of primes < n for n > 2 """
sieve = bytearray([True]) * (n//2)
for i in range(3,int(n**0.5)+1,2):
if sieve[i//2]:
sieve[i*i//2::i] = bytearray((n-i*i-1)//(2*i)+1)
return [2,*compress(range(3,n,2), sieve[1:])]
def factorization(n):
""" Returns a list of the prime factorization of n """
pf = []
for p in primeslist:
if p*p > n : break
count = 0
while not n % p:
n //= p
count += 1
if count > 0: pf.append((p, count))
if n > 1: pf.append((n, 1))
return pf
def divisors(n):
""" Returns an unsorted list of the divisors of n """
divs = [1]
for p, e in factorization(n):
divs += [x*p**k for k in range(1,e+1) for x in divs]
return divs
n = 600851475143
primeslist = primes(int(n**0.5)+1)
print(divisors(n))
【讨论】:
对于非常大的数字,这是迄今为止最快的方法。但是由于某种原因,当您将它放入文件并像通常从控制台一样运行它时,它会抛出SystemError: deallocated bytearray object has exported buffers
:例如,当您将n
设置为一个非常大的数字时,py -3 test.py
。 n = 326832565659962601981259122112549
。奇怪的是 - 当你直接从 python 控制台运行它时它可以工作 py -3
,但是当你运行 py -3 test.py
时会抛出错误【参考方案8】:
求一个数的因数的最简单方法:
def factors(x):
return [i for i in range(1,x+1) if x%i==0]
【讨论】:
【参考方案9】:我已经使用 timeit 尝试了大多数这些精彩的答案,以将它们的效率与我的简单功能进行比较,但我经常看到我的表现优于此处列出的那些。我想我会分享它,看看大家的想法。
def factors(n):
results = set()
for i in xrange(1, int(math.sqrt(n)) + 1):
if n % i == 0:
results.add(i)
results.add(int(n/i))
return results
正如它所写的那样,您必须导入数学来测试,但是用 n**.5 替换 math.sqrt(n) 应该也可以。我不会浪费时间检查重复项,因为无论如何重复项都不能存在于集合中。
【讨论】:
好东西!如果您将 int(math.sqrt(n)) + 1 放在 for 循环之外,您应该可以从中获得更多性能,因为不必在 for 循环的每次迭代中重新计算它 @TristanForward:这不是 Python 中 for 循环的工作方式。xrange(1, int(math.sqrt(n)) + 1)
被评估一次。
xrange
是 Python 2。这已经过时了。【参考方案10】:
进一步改进 afg & eryksun 的解决方案。 以下代码在不改变运行时渐近复杂度的情况下返回所有因子的排序列表:
def factors(n):
l1, l2 = [], []
for i in range(1, int(n ** 0.5) + 1):
q,r = n//i, n%i # Alter: divmod() fn can be used.
if r == 0:
l1.append(i)
l2.append(q) # q's obtained are decreasing.
if l1[-1] == l2[-1]: # To avoid duplication of the possible factor sqrt(n)
l1.pop()
l2.reverse()
return l1 + l2
想法:而不是使用 list.sort() 函数来获得一个排序列表,这给了 nlog(n) 复杂性;在需要 O(n) 复杂度的 l2 上使用 list.reverse() 要快得多。 (这就是python的制作方式。) 在 l2.reverse() 之后,可以将 l2 附加到 l1 以获取排序后的因子列表。
注意,l1 包含增加的 i-s。 l2 包含正在减少的 q-s。这就是使用上述想法的原因。
【讨论】:
相当肯定list.reverse
是 O(n) 而不是 O(1),并不是说它改变了整体复杂性。
是的,没错。我犯了一个错误。应该是 O(n)。 (我现在已将答案更新为正确的答案)
它比@steveha 或@agf 的解决方案慢2 倍左右。
您可以通过返回 l1 + l2.reversed()
而不是原地反转列表来获得小幅度 (2-3%) 的速度提升。【参考方案11】:
这是另一个没有 reduce 的替代方案,它在处理大量数字时表现良好。它使用sum
来展平列表。
def factors(n):
return set(sum([[i, n//i] for i in xrange(1, int(n**0.5)+1) if not n%i], []))
【讨论】:
这不是,它是不必要的二次时间。不要使用sum
或reduce(list.__add__)
来展平列表。【参考方案12】:
请务必抓住大于sqrt(number_to_factor)
的数字,以获取不寻常的数字,例如具有 3*3*11 和 floor sqrt(99)+1 == 10
的 99。
import math
def factor(x):
if x == 0 or x == 1:
return None
res = []
for i in range(2,int(math.floor(math.sqrt(x)+1))):
while x % i == 0:
x /= i
res.append(i)
if x != 1: # Unusual numbers
res.append(x)
return res
【讨论】:
它不会产生一个数字的所有因数。它计算一个数字的素数,例如x=8
expected: [1, 2, 4, 8]
, got: [2, 2, 2]
在@agf 给出的代码中计算 9 时找到 11。 `i = 9 -> 99%9 == 0 -> 9 和 99/9=11 已添加。【参考方案13】:
如果您想使用素数来加快速度,这是一个示例。这些列表很容易在 Internet 上找到。我在代码中添加了 cmets。
# http://primes.utm.edu/lists/small/10000.txt
# First 10000 primes
_PRIMES = (2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
73, 79, 83, 89, 97, 101, 103, 107, 109, 113,
127, 131, 137, 139, 149, 151, 157, 163, 167, 173,
179, 181, 191, 193, 197, 199, 211, 223, 227, 229,
233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
283, 293, 307, 311, 313, 317, 331, 337, 347, 349,
353, 359, 367, 373, 379, 383, 389, 397, 401, 409,
419, 421, 431, 433, 439, 443, 449, 457, 461, 463,
467, 479, 487, 491, 499, 503, 509, 521, 523, 541,
547, 557, 563, 569, 571, 577, 587, 593, 599, 601,
607, 613, 617, 619, 631, 641, 643, 647, 653, 659,
661, 673, 677, 683, 691, 701, 709, 719, 727, 733,
739, 743, 751, 757, 761, 769, 773, 787, 797, 809,
811, 821, 823, 827, 829, 839, 853, 857, 859, 863,
877, 881, 883, 887, 907, 911, 919, 929, 937, 941,
947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013,
# Mising a lot of primes for the purpose of the example
)
from bisect import bisect_left as _bisect_left
from math import sqrt as _sqrt
def get_factors(n):
assert isinstance(n, int), "n must be an integer."
assert n > 0, "n must be greather than zero."
limit = pow(_PRIMES[-1], 2)
assert n <= limit, "n is greather then the limit of 0".format(limit)
result = set((1, n))
root = int(_sqrt(n))
primes = [t for t in get_primes_smaller_than(root + 1) if not n % t]
result.update(primes) # Add all the primes factors less or equal to root square
for t in primes:
result.update(get_factors(n/t)) # Add all the factors associted for the primes by using the same process
return sorted(result)
def get_primes_smaller_than(n):
return _PRIMES[:_bisect_left(_PRIMES, n)]
【讨论】:
我在 Github 上创建了一个项目:github.com/Pierre-Thibault/Factor.【参考方案14】:一种可能比这里已经介绍的算法更有效的算法(特别是如果n
中有小的素数因子)。这里的诀窍是调整限制,每次找到主要因素时都需要试除法:
def factors(n):
'''
return prime factors and multiplicity of n
n = p0^e0 * p1^e1 * ... * pk^ek encoded as
res = [(p0, e0), (p1, e1), ..., (pk, ek)]
'''
res = []
# get rid of all the factors of 2 using bit shifts
mult = 0
while not n & 1:
mult += 1
n >>= 1
if mult != 0:
res.append((2, mult))
limit = round(sqrt(n))
test_prime = 3
while test_prime <= limit:
mult = 0
while n % test_prime == 0:
mult += 1
n //= test_prime
if mult != 0:
res.append((test_prime, mult))
if n == 1: # only useful if ek >= 3 (ek: multiplicity
break # of the last prime)
limit = round(sqrt(n)) # adjust the limit
test_prime += 2 # will often not be prime...
if n != 1:
res.append((n, 1))
return res
这当然还是试用师,没什么花哨的。因此它的效率仍然非常有限(特别是对于没有小除数的大数)。
这是python3;除法//
应该是你需要适应python 2 的唯一东西(添加from __future__ import division
)。
【讨论】:
【参考方案15】:如果您不想使用任何库,那么我认为这是最简单的方法:
def factors(n):
l = [] # empty list
# appending the factors in the list
for i in range(1,n+1):
if n%i==0:
l.append(i)
return l
【讨论】:
【参考方案16】:使用set(...)
会使代码稍微慢一些,只有在检查平方根时才真正需要。这是我的版本:
def factors(num):
if (num == 1 or num == 0):
return []
f = [1]
sq = int(math.sqrt(num))
for i in range(2, sq):
if num % i == 0:
f.append(i)
f.append(num/i)
if sq > 1 and num % sq == 0:
f.append(sq)
if sq*sq != num:
f.append(num/sq)
return f
if sq*sq != num:
条件对于像 12 这样的数字是必需的,其中平方根不是整数,但平方根的下限是一个因数。
请注意,此版本本身不会返回数字,但如果您愿意,这很容易解决。输出也没有排序。
我计时它在所有数字 1-200 上运行 10000 次,在所有数字 1-5000 上运行 100 次。它优于我测试过的所有其他版本,包括 dansalmo、Jason Schorn、oxrock、agf、steveha 和 eryksun 的解决方案,尽管 oxrock 是迄今为止最接近的。
【讨论】:
【参考方案17】:当我看到这个问题时,我感到非常惊讶,即使 numpy 比 python 循环快,也没有人使用 numpy。通过使用 numpy 实施 @agf 的解决方案,结果平均速度 8 倍。 我相信如果你在 numpy 中实现了一些其他的解决方案,你会得到惊人的结果。
这是我的功能:
import numpy as np
def b(n):
r = np.arange(1, int(n ** 0.5) + 1)
x = r[np.mod(n, r) == 0]
return set(np.concatenate((x, n / x), axis=None))
请注意,x 轴的数字不是函数的输入。函数的输入是 x 轴上的数字减去 1 的 2。 所以输入十的地方是 2**10-1 = 1023
【讨论】:
如果您要使用库,不妨选择合适的库:SymPy,如 Evgeni Sergeev 的回答所示。【参考方案18】:你的最大系数不超过你的数字,所以,让我们说
def factors(n):
factors = []
for i in range(1, n//2+1):
if n % i == 0:
factors.append (i)
factors.append(n)
return factors
瞧!
【讨论】:
【参考方案19】: import math
'''
I applied finding prime factorization to solve this. (Trial Division)
It's not complicated
'''
def generate_factors(n):
lower_bound_check = int(math.sqrt(n)) # determine lowest bound divisor range [16 = 4]
factors = set() # store factors
for divisors in range(1, lower_bound_check + 1): # loop [1 .. 4]
if n % divisors == 0:
factors.add(divisors) # lower bound divisor is found 16 [ 1, 2, 4]
factors.add(n // divisors) # get upper divisor from lower [ 16 / 1 = 16, 16 / 2 = 8, 16 / 4 = 4]
return factors # [1, 2, 4, 8 16]
print(generate_factors(12)) # 1, 2, 3, 4, 6, 12 -> pycharm output
Pierre Vriens hopefully this makes more sense. this is an O(nlogn) solution.
【讨论】:
【参考方案20】:我找到了一个在 python 中使用 cypari 库的简单解决方案。 这里是a link!
import cypari
def get_divisors(n):
divisors = cypari.pari('divisors()'.format(n))
return divisors
print(get_divisors(24))
输出
[1, 2, 3, 4, 6, 8, 12, 24]
【讨论】:
【参考方案21】:使用像下面的列表理解一样简单的东西,注意我们不需要测试 1 和我们试图找到的数字:
def factors(n):
return [x for x in range(2, n//2+1) if n%x == 0]
关于平方根的使用,假设我们想要找到 10 的因数。sqrt(10) = 4
的整数部分因此 range(1, int(sqrt(10))) = [1, 2, 3, 4]
和最多 4 的测试显然错过了 5。
除非我遗漏了我建议的内容,否则如果您必须这样做,请使用int(ceil(sqrt(x)))
。当然,这会产生很多不必要的函数调用。
【讨论】:
这个解决方案的问题是它检查了许多不可能是因子的数字——当你在找到较小的因子对。 @JasonSchorn:当你找到2的时候,你立刻知道10/2=5也是一个除数,不需要单独检查5! :)【参考方案22】:我认为@oxrock 的解决方案的可读性和速度是最好的,所以这里是为python 3+ 重写的代码:
def num_factors(n):
results = set()
for i in range(1, int(n**0.5) + 1):
if n % i == 0: results.update([i,int(n/i)])
return results
【讨论】:
【参考方案23】:循环直到在元组的 x 或 v 中找到重复项,其中 x 是分母,v 是结果。
number=30
tuple_list=[]
for i in np.arange(1,number):
if number%i==0:
other=int(number/i)
if any([(x,v) for (x,v) in tuple_list if (i==x) or (i==v)])==True:
break
tuple_list.append((i,other))
flattened = [item for sublist in tuple_list for item in sublist]
print(sorted(flattened))
输出
[1, 2, 3, 5, 6, 10, 15, 30]
【讨论】:
【参考方案24】:我们可以使用下面的 lambda 函数,
factor = lambda x:[(ele,x/ele) for ele in range(1,x//2+1) if x%ele==0 ]
因子(10)
输出:[(1, 10.0), (2, 5.0), (5, 2.0)]
此函数返回列表中给定数字的所有因子。
【讨论】:
【参考方案25】:import 'dart:math';
generateFactorsOfN(N)
//determine lowest bound divisor range
final lowerBoundCheck = sqrt(N).toInt();
var factors = Set<int>(); //stores factors
/**
* Lets take 16:
* 4 = sqrt(16)
* start from 1 ... 4 inclusive
* check mod 16 % 1 == 0? set[1, (16 / 1)]
* check mod 16 % 2 == 0? set[1, (16 / 1) , 2 , (16 / 2)]
* check mod 16 % 3 == 0? set[1, (16 / 1) , 2 , (16 / 2)] -> unchanged
* check mod 16 % 4 == 0? set[1, (16 / 1) , 2 , (16 / 2), 4, (16 / 4)]
*
* ******************* set is used to remove duplicate
* ******************* case 4 and (16 / 4) both equal to 4
* return factor set<int>.. this isn't ordered
*/
for(var divisor = 1; divisor <= lowerBoundCheck; divisor++)
if(N % divisor == 0)
factors.add(divisor);
factors.add(N ~/ divisor); // ~/ integer division
return factors;
【讨论】:
这里几乎所有的算法都将范围限制为* .5,但实际上这个范围要小得多。它实际上是数字的平方。如果我们有较低的除数,我们可以很容易地得到较高的除数。因为它只是数字/除数。对于 16,我得到 4 的 sqrt,然后从 1 循环到 4。因为 2 是 16 的下界除数,我们需要 16 / 2 得到 8。如果我们有 1,那么得到 16 是(16 / 1)。我在学习素数分解时想到了这个,所以我不知道它是否在其他地方发布,但它甚至适用于大量数字。我可以提供一个python解决方案。 应该在python中【参考方案26】:我认为这是最简单的方法:
x = 23
i = 1
while i <= x:
if x % i == 0:
print("factor: %s"% i)
i += 1
【讨论】:
您的回答虽然给出了正确的结果,但效率很低。看看接受的答案。解释它如何解决问题总是有助于答案更有用。以上是关于在 Python 中查找数字的所有因数的最有效方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章