找到Python中筛选生成的第n个幸运数字

时间:2014-03-08 22:46:51

标签: python

我正在尝试在Python中创建一个程序,它将根据lucky number sieve生成第n个幸运数字。我是Python的新手,所以我不知道如何做到这一点。到目前为止,我已经想出如何制作一个能够确定低于指定数字的所有幸运数字的函数:

def lucky(number):
    l = range(1, number + 1, 2)
    i = 1
    while i < len(l):
        del l[l[i] - 1::l[i]]
        i += 1
    return l

有没有办法修改这个,以便我可以找到第n个幸运数字?我想到逐渐增加指定的数字,直到找到找到所需幸运数字的适当长度的列表,但这似乎是一种非常低效的方式。

编辑:我想出了这个,但还有更好的方法吗?

def lucky(number):
    f = 2
    n = number * f
    while True:
        l = range(1, n + 1, 2)
        i = 1
        while i < len(l):
            del l[l[i] - 1::l[i]]
            i += 1
        if len(l) >= number:
            return l[number - 1]
        f += 1
        n = number * f

3 个答案:

答案 0 :(得分:4)

  

我想出了这个,但有更好的方法吗?

事实是,总是是更好的方式,剩下的问题是:足够满足您的需求吗?

一种可能的改进是将所有这些变成发电机功能。这样,您只会在消耗时计算新值。我想出了这个版本,我只验证了大约60个术语:

import itertools


def _idx_after_removal(removed_indices, value):
    for removed in removed_indices:
        value -= value / removed
    return value


def _should_be_excluded(removed_indices, value):
    for j in range(len(removed_indices) - 1):
        value_idx = _idx_after_removal(removed_indices[:j + 1], value)
        if value_idx % removed_indices[j + 1] == 0:
            return True
    return False


def lucky():
    yield 1
    removed_indices = [2]
    for i in itertools.count(3, 2):
        if not _should_be_excluded(removed_indices, i):
            yield i
            removed_indices.append(i)
            removed_indices = list(set(removed_indices))
            removed_indices.sort()

如果要从此生成器中提取第100个术语,可以使用itertools nth recipe

def nth(iterable, n, default=None):
    "Returns the nth item or a default value"
    return next(itertools.islice(iterable, n, None), default)

print nth(lucky(), 100)

我希望这有效,并且毫无疑问有更多的代码改进空间(但如前所述,总是需要改进的空间!)。

答案 1 :(得分:0)

使用numpy数组,您可以使用布尔索引,这可能会有所帮助。例如:

>>> a = numpy.arange(10)
>>> print a
[0 1 2 3 4 5 6 7 8 9]

>>> print a[a > 3]
[4 5 6 7 8 9]

>>> mask = np.array([True, False, True, False, True, False, True, False, True, False])
>>> print a[mask]
[0 2 4 6 8]

这是使用numpy数组的幸运数字函数:

import numpy as np

class Didnt_Findit(Exception):
    pass

def lucky(n):
    '''Return the nth lucky number.

    n --> int

    returns int
    '''

    # initial seed
    lucky_numbers = [1]
    # how many numbers do you need to get to n?
    candidates = np.arange(1, n*100, 2)
    # use numpy array boolean indexing
    next_lucky = candidates[candidates > lucky_numbers[-1]][0]

    # accumulate lucky numbers till you have n of them
    while next_lucky < candidates[-1]: 
        lucky_numbers.append(next_lucky)
        #print lucky_numbers
        if len(lucky_numbers) == n:
            return lucky_numbers[-1]
        mask_start = next_lucky - 1
        mask_step = next_lucky
        mask = np.array([True] * len(candidates))
        mask[mask_start::mask_step] = False
        #print mask
        candidates = candidates[mask]
        next_lucky = candidates[ candidates > lucky_numbers[-1]][0]
    raise Didnt_Findit('n = ', n)

>>> print lucky(10)
33

>>> print lucky(50)
261

>>> print lucky(500)
3975

检查我和@ icecrime的输出10,50和500 - 他们匹配。

你的速度比我快得多,而且用n来扩展得更好。

答案 2 :(得分:-1)

n=input('enter n ')
a= list(xrange(1,n))
x=a[1]
for i in range(1,n):
    del a[x-1::x]
    x=a[i]
    l=len(a)

    if i==l-1:
        break

print "lucky numbers till %d" % n
print a  


lets do this with an example.lets print lucky numbers till 100
put n=100
firstly a=1,2,3,4,5....100
x=a[1]=2
del a[1::2] leaves 
a=1,3,5,7....99
now l=50
and now x=3
then del a[2::3] leaving a =1,3,7,9,13,15,.....
and loop continues till i==l-1