从Python的奇数/偶数列表中删除偶数/奇数
问题内容:
我试图更好地理解Python中的列表理解。我通过一个不太雅致的解决方案完成了关于代码战的在线挑战,如下所示。
挑战是:
- 给定一个偶数和一个奇数的列表,返回奇数
- 给定一个奇数和一个偶数的列表,返回偶数
我对此的(模糊的)解决方案是:
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)
哪个工作正常,但似乎蛮力的。我错了的思想,开始像占位符列表(最)功能o
,并e
很“小白样”?
我想更好地理解为什么此解决方案适用于奇数列表,但在偶数列表上失败,以更好地理解列表理解:
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
。
预先感谢您的任何见解。
问题答案:
因为你的第一个尝试失败if
时 总是要真实 。您将始终拥有至少包含1个元素的列表;要么单数是奇数,并且您测试了带有所有偶数的列表,否则您的列表中就有
一个 偶数。只有一个 空 列表将为假。
列表理解不是最好的解决方案,不是。尝试用最少的元素检查数来解决(如果前两个元素在类型上不同,则获得第三个来打破平局,否则迭代直到找到不适合尾部的元素):
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)
StopIteration
如果输入可迭代输入中的元素少于3个,或者没有异常,则以上内容将引发异常。它也不会处理一个以上异常的情况(例如2个偶数后跟2个奇数;在这种情况下将返回第一个奇数)。