在python中寻找具有特定条件的数字
Posted
技术标签:
【中文标题】在python中寻找具有特定条件的数字【英文标题】:Looking for a number with specific conditions in python 【发布时间】:2015-09-25 11:34:49 【问题描述】:所以我需要创建一个函数来找到可以除以 2,3,4,5,6,7,8,9,10 的最小自然数
这是我目前得到的:
def divisible():
number= 2
if number % 2 == 0:
if number % 3 == 0:
if number % 5 == 0:
if number % 7 == 0:
if number % 9 == 0:
print number
else:
number = number + 2
divisible()
这就是我在那里所做的:
如果自然数完全可以被2整除,那么它也可以被4整除,10和5也是如此,所以我把它们去掉了。然后我正在检查除法是否可以完全由所有其他数字完成。我的想法是打印可以通过所有这些条件(如果)的数字。
另外,由于我要查找的数字可以除以 2,这意味着它必须是偶数,所以我每次都加 2。
这个想法是找到一个可以完全除以 2、3、4、5、6、7、8、9 和 10 的数字,然后打印该数字。
有人可以帮忙吗?
【问题讨论】:
你的问题到底是什么? 我的功能不起作用,我正在寻求提示或想法以使其正常工作。 @MrSpeedArt:你需要告诉我们这里的 works 是什么意思。你期待什么输出?您应该提供该功能的任何输入吗?你会得到什么? @MartijnPieters 我期待一个数字,唯一的输入是我要检查的数字,但它们已经在函数中。我没有得到函数的响应,比如找不到号码。 @MrSpeedArt:那是因为您将number = 2
设置在顶部并且从不更改它。所以其他测试都不会通过。
【参考方案1】:
您的代码没有循环数字; number
保持静态,并且由于 number = 2
,其他测试都失败了。那是因为你没有在这里循环。
您还从测试中排除了错误的数字;能被 2 整除的数不一定能被 10 整除,反之亦然。所以你需要在这里测试 6、7、8、9 和 10。您可以使用all()
来测试一系列数字,而不是一组嵌套的if
语句:
n = 0
while True:
n += 10
if all(n % i == 0 for i in (6, 7, 8, 9)):
print(n)
break
您至少需要增加 10,并且一旦以 10 为步长增加,测试它是否也能被 10 整除是没有意义的。
这生成第一个这样的数字。如果您需要测试一个数字是否可以被所有这些因素整除,请使用%
来测试这 5 个数字是否没有余数:
def is_divisible(n):
return all(n % i == 0 for i in (6, 7, 8, 9, 10))
【讨论】:
肯定不是“6 * 7 * 8 * 9 * 10 = 30240 的倍数”。答案不是不到十分之一吗? @Duncan:呃,脑子里塞满了寒冷,我今天也惨败了。实数是2520,从4、7、9和10,或5、7、8和9,或5 * 7 * (2 ^ 3) * (3 ^ 2)..【参考方案2】:每次您调用divisible()
时,您将number
设置为2。您将永远无法到达else
。您需要在函数外部将number
设置为2,然后以number
作为参数在循环中调用函数,直到找到您要查找的数字。
即:
def divisible(num):
# here code to test in num is entirely divisible by number you want
return result # True is divisible, False if not divisible
并循环调用这个函数:
x = 2
while not divisible(x):
x = x + 2
print "Number " + str(x) + " is the minimum number entirely divisible by 2, 3, 4, 5, 6, 7, 8, 9 and 10."
请注意,这不是找到此类数字的最佳算法。
【讨论】:
【参考方案3】:这行得通:
def divisible():
residu=0
numero = 1
for x in range(1,11): #Per a cada valor en el for definim el residu
residu = numero%x + residu
if (residu==0):#En cas de que el residu dongui 0, creem una variable div que será el nostre número i la definim com la variable del numero que anem provant
div = numero
while (residu != 0):#Si el residu es diferent de 0
numero=numero+1
residu=0
for x in range(1,11):#Per a cad valor del for calculem el residu i el sumem als residus de les operacions anteriors
residu = numero%x + residu
if (residu==0):#Si el residu dona 0, el numero es la nostra solució
div = numero
print div
可分割()
【讨论】:
【参考方案4】:这道题是计算最小公倍数 (LCM) 的问题。解决它的几种标准方法是使用最大公约数 (GCD)、素数分解和约简。
GCD 开始发挥作用,因为对于两个整数 a 和 b,
GCD(a,b)*LCM(a,b) = a*b
众所周知,使用欧几里得算法计算 GCD,虽然可能不是那个名字,但可以表示为
def gcd(x,y):
while y:
x,y = y,x%y
return abs(x)
两个数字的 GCD 和 LCM 本身并不能解决两个以上的问题,但是它们都具有关联性,这是减少两个以上数字的设置。这意味着:
GCD(a,b,c,d)=GCD(GCD(GCD(a,b),c),d) # associativity
LCM(a,b,c,d)=LCM(LCM(LCM(a,b),c),d) # associativity
还有一些有趣的功能
reduce(fun,[a,b,c,d])
等价于
fun(fun(fun(a,b),c),d) # expanded reductive form
这意味着
GCD(a,b,c,d) = reduce(GCD,[a,b,c,d])
LCM 关联性还意味着只需要一个两个参数的 LCM 函数来减少超过两个,并且不需要 GCD。这很好,因为它减少了开销,因为直接计算 LCM 所需的操作比使用 GCD 少。
如果您想知道,GCD 和 LCM 也是可交换的。这仅仅意味着参数列表中元素的顺序不会影响结果。
根据这些信息、对 150 多个 LCM 实现的回顾和一些测试,以下 Python LCM 函数在性能和简单性方面表现最佳:
def lcm(*args):
def lcm2(x,y):
tmp=x
while (tmp%y)!=0:
tmp+=x
return tmp
return reduce(lcm2,args)
此函数来自 Eratosthenes 在Least common multiple for 3 or more numbers 上的回答。
让我们看看它在使用 Python 3.4.3 x64 时的表现
from functools import reduce
a = [2, 3, 4, 5, 6, 7, 8, 9, 10]
lcm(*a)
Out[9]: 2520
timeit lcm(*a)
100000 loops, best of 3: 5.95 µs per loop
timeit lcm(2, 3, 4, 5, 6, 7, 8, 9, 10)
100000 loops, best of 3: 5.9 µs per loop
对于 Python 2.7.10 x64
lcm(*a)
Out[60]: 2520
timeit lcm(*a)
100000 loops, best of 3: 4.36 µs per loop
timeit lcm(2, 3, 4, 5, 6, 7, 8, 9, 10)
100000 loops, best of 3: 4.33 µs per loop
LCM 也可以使用素数分解来计算。算术基本定理,也称为唯一因式分解定理,它说“每个大于 1 的整数要么是素数本身,要么是素数的乘积,并且这个乘积是唯一的,直到因式的顺序。”这意味着除数列表中的每个除数都有一个素数分解,并且所有这些分解中的每个素数至少出现一个除数的最大次数。因此,可以被所有除数(也就是它们的 LCM)均分的最小自然数是所有出现的素数的乘积,每个素数都提高到其最大次数的幂。下面是这个方法的实现代码:
from collections import defaultdict
from operator import mul
try:
reduce
except:
from functools import reduce
def findmnn(a):
def prime_factors(n):
factors = defaultdict(int)
d = 2
step = 1
while d*d <= n:
while n>1:
while n%d == 0:
factors[d] += 1
n = n/d
d += step
step = 2
return factors
d = defaultdict(int)
for i in a:
p = prime_factors(i)
for j in p:
if p[j] > d[j]:
d[j] = p[j]
return reduce(mul, map(lambda x: x**d[x], d))
给定除数列表为
a = [2, 3, 4, 5, 6, 7, 8, 9, 10]
findmnn(a)
Out[3]: 2520
使用 Python 2.7.10 x64 使用 timeit 进行测试
timeit findmnn(a)
10000 loops, best of 3: 23.1 µs per loop
在同一平台上使用 Python 3.4.3 x64 使用 timeit 进行测试:
timeit findmnn(a)
10000 loops, best of 3: 49.4 µs per loop
为了比较和在同一平台上:
def mpmnn():
n = 0
while True:
n += 10
if all(n % i == 0 for i in (6, 7, 8, 9)):
return n
使用 Python 2.7.10 x64
timeit mpmnn()
1000 loops, best of 3: 245 µs per loop
使用 Python 3.4.3 x64
timeit mpmnn()
1000 loops, best of 3: 244 µs per loop
这里有一些参考资料
-
Least Common Multiple (Wolfram World)
Least Common Multiple Code Examples (Rosetta Code)
Greatest Common Divisor (Wolfram World)
Euclidean Algorithm (Wolfram World)
Fundamental theorem of arithmetic (WikepediA)
【讨论】:
我想我找到了一个更短的函数,但感谢您提供的信息。 @MrSpeedArt:干得好!如果它运行得更快并优化我的解决方案以提高速度,我会很感兴趣。顺便说一句,这被称为“最小公倍数”或 lcm 问题。在rosettacode.org/wiki/Least_common_multiple#Python 尝试了“多次迭代”功能,但它的运行速度比我的慢得多。对于一组大数,它可以通过更好的素数来改进分解函数,例如使用 Croft 螺旋算法的函数,但再次使用该函数会增加使用输入数据的运行时间。 @MrSpeedArt:在查看了 150 多个实现之后,我发现其中一个可以在 6µs 内运行您的数据,并且只有 7 行长。它发布在我的答案中,它回顾了几种计算最小公倍数的方法。参考文献已在末尾添加。以上是关于在python中寻找具有特定条件的数字的主要内容,如果未能解决你的问题,请参考以下文章
Selenium CSS_Selector 正在寻找具有特定文本的元素,结果是“NoSuchElementException”