从整数列表中查找具有最大除数的整数

时间:2016-02-16 01:52:38

标签: python python-3.x

我正在尝试编写一个函数来从列表中查找具有最大除数的整数,但是输出错误了。这就是我的功能。

def find_my_integer_divisor(mylist):
      def find_divisor(k):
            count =0
            for i in range (1,k+1):
                  if k%i==0:
                      count +=1
            return count 
     A=mylist[0]
     for x in mylist [0:]:
           A=find_divisor(x)
     return A

它返回mylist中最后一个条目的计数。我知道我必须比较每个条目的值计数并返回计数最多但却不知道如何操作的整数。

4 个答案:

答案 0 :(得分:1)

这应该有效:

def find_divisor(k):
     count =0
     for i in range (1,k+1):
           if k%i==0:
               count +=1
     return count

def find_my_integer_divisor(mylist):
     return max(mylist, key=find_divisor)

答案 1 :(得分:1)

我们可以通过进行素数分解来更有效地计算可能的数量,而不是实际找到所有适当的因素。

例如,

288 == 2**5 * 3**2

和适当因素的数量是

  (5 + 1) * (2 + 1) - 1
    ^         ^       ^
number     number    omit one case:
of twos   of threes  5 2s and 2 3s == 288,
used in   used in    which is not a proper
factor,    factor    factor of itself
 0..5
(six possible
  values)

要进行素数分解,我们需要从生成素数开始:

def primes(known_primes=[7, 11, 13, 17, 19, 23, 29]):
    """
    Generate every prime number in ascending order
    """
    # 2, 3, 5 wheel
    yield from (2, 3, 5)
    yield from known_primes
    # The first time the generator runs, known_primes
    #   contains all primes such that  5 < p < 2 * 3 * 5
    # After each wheel cycle the list of known primes
    #   will be added to.
    # We need to figure out where to continue from,
    #   which is the next multiple of 30 higher than
    #   the last known_prime:
    base = 30 * (known_primes[-1] // 30 + 1)
    new_primes = []
    while True:
        # offs is chosen so  30*i + offs cannot be a multiple of 2, 3, or 5
        for offs in (1, 7, 11, 13, 17, 19, 23, 29):
            k = base + offs    # next prime candidate
            for p in known_primes:
                if not k % p:
                    # found a factor - not prime
                    break
                elif p*p > k:
                    # no smaller prime factors - found a new prime
                    new_primes.append(k)
                    break
        if new_primes:
            yield from new_primes
            known_primes.extend(new_primes)
            new_primes = []
        base += 30

可以像

一样进行测试
from itertools import islice
print(list(islice(primes(), 500)))

[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, ...

现在我们有素数,我们可以计算每个素因子的出现次数:

def prime_factor_count(n):
    """
    Factorize n and yield (factor, count) for each distinct factor
    """
    if n < 2:
        return
    else:
        for p in primes():
            count = 0
            while not n % p:
                count += 1
                n //= p
            if count:
                yield (p, count)
                if n == 1:
                    # number is fully factored
                    break
                elif p*p > n:
                    # no smaller prime factors - remainder is prime
                    yield (n, 1)
                    break

我们可以测试

print(list(prime_factor_count(288)))    # => [(2, 5), (3, 2)]

您应该从上面识别288 == 2**5 * 3**2。现在我们可以

def num_proper_factors(n):
    total_factors = 1
    for factor, count in prime_factor_count(n):
        total_factors *= (count + 1)
    return total_factors - 1

测试类似

print(num_proper_factors(288))     # => 17

最后,

def num_with_most_divisors(lst):
    return max(lst, key=num_proper_factors)

QED。

答案 2 :(得分:0)

简短回答:使用max与@rofls显示的关键功能find_divisor一起使用。

长答案:在每次迭代中,您需要将您之前的值与列表中的当前值进行比较,如果当前值具有更大的除数变化计数A,否则不要&# 39; t,你的代码中的问题是你没有做这个检查。你可以做这样的事情

def max_divisor_count(my_list):
    result = my_list[0]
    for n in my_list[1:]: # start in 1 because 0 is already in result
        if find_divisor(n) > find_divisor(result):
            result = n
    return result 

这与具有键功能解决方案的max大致相同。

当然,这可以进一步改进,以避免像这样的重复计算

def max_divisor_count(my_list):
    result = my_list[0]
    div_count = find_divisor(result)
    for n in my_list[1:]: # start in position 1 because 0 is already in result
        if result != n:
            temp = find_divisor(n) 
            if temp > div_count:
                result = n
                div_count = temp
    return result 

答案 3 :(得分:0)

这是一个生成器表达式替代方案。注意我使用enumerate来创建2个生成器实例。第一个是计算最大值,第二个是计算from itertools import tee lst = [1, 2, 3, 6, 8, 10, 14] gen1, gen2 = tee(sum(k%i==0 for i in range(1, k+1)) for k in lst) divmax = max(gen1) [lst[i] for i, j in enumerate(gen2) if j == divmax] # [6, 8, 10, 14]

下面的示例还演示了如何使用列表推导来返回具有最大除数的所有整数。

&&