【问题标题】:Check if list contains alternating primes and perfect squares检查列表是否包含交替素数和完美正方形
【发布时间】:2019-07-10 08:48:40
【问题描述】:

我刚刚开始使用 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)

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

【问题讨论】:

    标签: python list python-3.6 primes


    【解决方案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)
    

    【讨论】:

      【解决方案2】:

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

      假设不需要的列表是代表偶数和奇数元素的两个列表,那么我们可以解决这个问题。 (消除素数和正方形列表是一个完整的“另一个问题”。)下面是我对您的代码的修改——我们不创建额外的列表,而是使用几个可重用的 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),并使用了上面的集合,但他的解决方案生成了您想要消除的相同列表(只是以集合的形式)。

      【讨论】:

        【解决方案3】:

        我想出了这个解决方案:

        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
        

        【讨论】:

        • 因为它根本没有任何额外的列表,所以这个解决方案有真正的优点。不幸的是,这可能会被它对 Python 的非惯用用法所掩盖。征得您的许可,我想编辑您的答案以重新编写代码以使代码更清晰,并提高效率。如果您对我的更改不满意,我们可以随时回滚。
        • 为了提高效率,我重写了你的 squares 和 primes 函数,这样它们就不会成为你答案的焦点,这实际上是 primesquare() 函数。在其中,我调整了sp 的值,以反映列表的第一个元素已经过测试,因此不需要在完整列表测试中再次测试。并整理了您的布尔测试。
        猜你喜欢
        • 1970-01-01
        • 2022-08-23
        • 2015-11-06
        • 2016-03-07
        • 2016-07-03
        • 2020-10-03
        • 1970-01-01
        相关资源
        最近更新 更多