从奇数/偶数Python列表中删除偶数/奇数

时间:2016-09-28 14:30:57

标签: python list list-comprehension

我试图更好地理解Python中的列表理解。我完成了对代码战的在线挑战,其中包含一个相当不优雅的解决方案,如下所示。

挑战是:

  1. 给出一个偶数列表和一个奇数,返回奇数
  2. 给出奇数和偶数列表,返回偶数
  3. 我(不优雅)的解决方案是:

    def find_outlier(integers):
        o = []
        e = []
        for i in integers:
            if i % 2 == 0:
                e.append(i)
            else:
                o.append(i)
        # use sums to return int type
        if len(o) == 1:
            return sum(o)
        else:
            return sum(e)
    

    哪种方法很好,但似乎相当蛮力。我认为使用oe这样的占位符列表开始(大多数)功能是非常的" noob-like"我错了?

    我希望更好地理解为什么这个解决方案适用于奇数列表,但是在偶数列表中失败,以便更好地理解列表理解:

    def find_outlier(integers):
        if [x for x in integers if x % 2 == 0]:
           return [x for x in integers if x % 2 == 0]
        elif [x for x in integers if x % 2 != 0]:
           return [x for x in integers if x % 2 != 0]
        else:
            print "wtf!"
    
    o = [1,3,4,5]
    e = [2,4,6,7]
    
    In[1]: find_outlier(o)
    Out[1]: [4]
    
    In[2]: find_outlier(e)
    Out[2]: [2, 4, 6]
    

    Out[2]应该返回7

    提前感谢任何见解。

3 个答案:

答案 0 :(得分:6)

您的尝试失败,因为第一个if 始终是真的。你总会有一个至少包含1个元素的列表;要么奇数输出是奇数,你测试了一个包含所有偶数的列表,否则你有一个包含一个偶数的列表。只有列表才会出错。

列表理解不是最好的解决方案,不是。尝试用最少的元素数来解决它(前2个元素,如果它们的类型不同,则获得第3个以打破平局,否则迭代直到找到不适合尾部的元素):

def find_outlier(iterable):
    it = iter(iterable)
    first = next(it)
    second = next(it)
    parity = first % 2
    if second % 2 != parity:
        # odd one out is first or second, 3rd will tell which
        return first if next(it) % 2 != parity else second
    else:
        # the odd one out is later on; iterate until we find the exception
        return next(i for i in it if i % 2 != parity)

如果输入可迭代中的元素少于3个,或者没有找到异常,则上述将抛出StopIteration异常。它也不会处理有多个异常的情况(例如2甚至后跟2个奇数;在这种情况下将返回第一个奇数值)。

答案 1 :(得分:0)

此响应有哪些缺点(位于this particular challenge上的解决方案堆栈的顶部)?

def find_outlier(int):
    odds = [x for x in int if x%2!=0]
    evens= [x for x in int if x%2==0]
    return odds[0] if len(odds)<len(evens) else evens[0]

答案 2 :(得分:-1)

最有效的答案是变得有点难看。

def f(in_list):
    g = (i for i in in_list)
    first = next(g)
    second = next(g) #The problem as described doesn't make sense for fewer than 3 elements.  Let them handle the exceptions.
    if first%2 == second%2:
        a = first%2
        for el in g:
            if el%2 != a:
                return el
    else:
        third = next(g)
        if third%2 == first%2:
            return second
        else:
            return first
    except ValueError('Got a bad list, all evens or all odds')