检查列表是否包含交替质数和完美平方

时间:2019-02-16 11:04:43

标签: python list python-3.6 primes

我刚刚开始使用Python编程。我在检查给定列表是否包含素数和完美平方的交替序列时遇到问题。该列表可以以素数或完美的正方形开头。我想出了一个解决方案,但是它效率不高,因为它会生成不需要的列表。使用更高效的Python代码能否做到?

首先,我正在创建函数以生成素数列表以及达到测试列表最大值的理想平方。函数squaretest()primecheck()


def squaretest(num):
    sqlist=[]
    i=1
    while i**2 <= num:
        sqlist.append(i**2) 
        i+=1
    return sqlist

def primecheck(num):
    primelist=[]
    for i in range(2,num + 1):
            for p in range(2,i):
                if (i % p) == 0:
                    break
            else:
                primelist.append(i)
    return primelist

然后,我将给定的列表分为偶数索引和奇数索引元素的列表,并根据primelistsquarelist检查它们的所有元素:

def primesquare(l):
    if len(l)==1:
        primelist = primecheck(l[0])
        sqlist = squaretest(l[0])
        return (l[0] in primelist) or (l[0] in sqlist)
    else:
        ol=[]
        el=[]
        for i in range(0,len(l),2):
            ol.append(l[i])
        for p in range (1, len(l),2):
            el.append(l[p])
        primelist = primecheck(max(l))
        sqlist = squaretest (max(l))
        return((all(x in primelist for x in el)) == True and (all(y in sqlist for y in ol)) == True) or ((all(x in primelist for x in ol)) == True and (all(y in sqlist for y in el)) == True)

有效。 任何建议都会很有帮助。

3 个答案:

答案 0 :(得分:1)

您可以使用sets检查列表中的所有成员是否都在另一个列表中。

def primesquare(l):
    if len(l) == 0:
        return True

    primelist = set(primecheck(max(l)))
    sqlist = set(squaretest(max(l)))

    ol = set(l[::2])
    el = set(l[1::2])

    odds_are_primes = ol.issubset(primelist)
    odds_are_squares = ol.issubset(sqlist)
    evens_are_primes = el.issubset(primelist)
    evens_are_squares = el.issubset(sqlist)

    return (odds_are_primes and evens_are_squares) or (odds_are_squares and evens_are_primes)

答案 1 :(得分:1)

  

我想出了一个解决方案,但是它产生的效率不高   不需要的列表。

假设不想要的列表是代表偶数和奇数元素的两个列表,那么我们可以对其进行修复。 (消除素数和平方列表是一个完整的“另一个问题。”)下面是我对您的代码的修改-我们不创建其他列表,而是创建几个可重复使用的 ranges ,它们是根据需要产生整数序列,但不存储在内存中。

您的any()设计效率很高,因为自变量是生成器表达式,而不是根据需要计算的列表。一旦在数组中发现缺陷,整个过程就会停止并返回False -它不需要处理其余部分:

def squares(number):
    return {x * x for x in range(int(number ** 0.5) + 1)}

def primes(number):
    prime_set = set()

    for i in range(2, number + 1):
        for p in range(2, int(i ** 0.5) + 1):
            if (i % p) == 0:
                break
        else:  # no break
            prime_set.add(i)

    return prime_set

def primesquare(array):
    if not array:
        return True  # define as the problem demands

    length, maximum = len(array), max(array)

    odd, even = range(0, length, 2), range(1, length, 2)

    prime_set, square_set = primes(maximum), squares(maximum)

    return all(array[i] in prime_set for i in even) and all(array[i] in square_set for i in odd) or all(array[i] in prime_set for i in odd) and all(array[i] in square_set for i in even)

我欣赏@AndreySemakin的基于集合的解决方案(+1),并使用上面的集合,但是他的解决方案生成了您想要消除的相同列表(只是以集合的形式)。

答案 2 :(得分:1)

我想出了以下解决方案:

def primesquare(lst):

    # checking if the first element is either perfect square or a prime
    if not lst or (not checksquare(lst[0]) and not checkprime(lst[0])):
        return False

    length = len(lst)

    if length == 1:
        return True

    if checksquare(lst[0]):
        # if first element is square then make s(quare)=2 and p(rime)=1
        s, p = 2, 1
    else:
        # if first element is prime then make s=1 and p=2
        s, p = 1, 2

    # running perfect square loop from s to len-1 with gap of 2 and checking condition
    for i in range(s, length, 2):
        if not checksquare(lst[i]):
            return False

    # running prime loop from p to len-1 with gap of 2
    for i in range(p, length, 2):
        if not checkprime(lst[i]):
            return False

    return True

def checksquare(n):  # function to check perfect square

    if n < 0:
        return False

    if 0 <= n <= 1:
        return True

    for i in range(int(n ** 0.5) + 1):
        if i * i == n:
            return True

    return False

def checkprime(n):  # function to check prime

    if n < 2:
        return False

    if n % 2 == 0:
        return n == 2

    for i in range(3, int(n ** 0.5) + 1, 2):
        if n % i == 0:
            return False

    return True