类似'Fizzbuzz'的算法

时间:2013-12-31 11:46:56

标签: python

我有一个功能

def process_list(mylist):
    return [x for x in mylist if isinstance(x, int)];

我需要修改这个函数,以便在返回的新列表中,每个可被3整除的整数被-1替换,每个可被5整除的整数被-2替换,并且被二者整除的每个整数都被替换为-3。其他整数保持不变。和之前一样,非整数应该被删除。

因此,process_list([1, 3, 5, 15, 22, 'b'])应返回[1, -1, -2, -3, 22].

我可以使用if-else来做到这一点。但我想知道这样做的pythonic方式。

4 个答案:

答案 0 :(得分:1)

嗯,pythonic对我来说不是单行的同义词。 请参阅this

因为flat is better than nestedsparse is better than dense

def process_list(mylist):
    # filter, prefer generator expression
    tmp = (x for x in mylist if isinstance(x, int))

    # mapping logic
    mappings = ((15, -3), (5, -2), (3, -1))
    def fizzbuzz(num):
        try:
            return next(v for k, v in mappings if num%k == 0)
        except StopIteration:
            return num 
    # return a mapped list
    return map(fizzbuzz, tmp)

答案 1 :(得分:0)

我认为在这种情况下,使用if-else的pythonic方式

例如

def process_list(mylist):
    return list_filter(x) for x in mylist if isinstance(x, int)]

def list_filter(x):
    if x % 3 == 0:
         return -1
    elif ... # <snip>

(尽管我可能会将process_list函数重写为构建新列表的for循环)

使用列表理解很可能只是很多难以阅读,和/或需要多次传递

答案 2 :(得分:0)

您可以更改此功能。

def process_list(mylist):
    return [(-3 if x % 15 == 0 else (-2 if x % 5 == 0 else ( -1 if x % 3 == 0 else x))) for x in mylist if isinstance(x, int)]

答案 3 :(得分:0)

我不能说这是最好的方式,但作为一个不喜欢长 if ... else 链的人,我会将HannesOvrén的过滤器重写为< / p>

def convert_ints(x, dividers=(15, 5 ,3)):
    for val, div in enumerate(dividers):
        if (x%div)==0:
            return -len(dividers)+val
    return x

这是一个可以轻松扩展的scalbale解决方案 修改 对于更复杂的情况,可以使用 lamdba -s元组:

conditions=(lambda x:x%15==0, lambda x:x%5==0, lambda x:x%3==0)