在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中寻找具有特定条件的数字的主要内容,如果未能解决你的问题,请参考以下文章

python使用正则表达式寻找具有特定后缀的文件

编程之美快速寻找满足条件的两个数

在d3js中寻找具有特定投影的世界地图

Selenium CSS_Selector 正在寻找具有特定文本的元素,结果是“NoSuchElementException”

在时间序列中寻找异方差性

Python 如何在list里寻找一个数字