从奇数/偶数Python列表中删除偶数/奇数
我试图更好地理解Python中的列表理解。我用一个相当不雅观的解决方案完成了一个关于codewars的在线挑战,如下所示 挑战是: 给定偶数和奇数的列表,返回奇数 给定一个奇数和一个偶数的列表,返回偶数 我对此不雅观的解决方案是:从奇数/偶数Python列表中删除偶数/奇数,python,list,list-comprehension,Python,List,List Comprehension,我试图更好地理解Python中的列表理解。我用一个相当不雅观的解决方案完成了一个关于codewars的在线挑战,如下所示 挑战是: 给定偶数和奇数的列表,返回奇数 给定一个奇数和一个偶数的列表,返回偶数 我对此不雅观的解决方案是: def find_outlier(integers): o = [] e = [] for i in integers: if i % 2 == 0: e.append(i) else:
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)启动大多数函数是非常类似noob的想法是错误的吗
为了更好地理解列表理解,我想更好地理解为什么此解决方案适用于奇数列表,但在偶数列表上失败:
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]
Where Out[2]应该返回7
提前感谢您提供的任何见解。您的尝试失败了,因为第一个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)
如果输入iterable中的元素少于3个,或者找不到异常,则上面的代码将抛出StopIteration异常。它也不会处理存在多个异常的情况,例如2偶数后跟2奇数;在这种情况下,将返回第一个奇数值。您的尝试失败,因为第一个if总是为true。您将始终拥有一个至少包含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)
如果输入iterable中的元素少于3个,或者找不到异常,则上面的代码将抛出StopIteration异常。它也不会处理存在多个异常的情况,例如2偶数后跟2奇数;在这种情况下,将返回第一个奇数值。最有效的答案将变得有点难看
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')
最有效的答案是变得有点难看
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')
这个位于解决方案堆栈顶部的响应有哪些缺点
这个位于解决方案堆栈顶部的响应有哪些缺点
列表理解不是这里的最佳解决方案,不是。试着用最少数量的元素来解决它。检查前2个元素,如果它们的类型不同,请使用第3个元素来打破这种关系,否则就迭代,直到找到一个不适合尾部的元素。@D8Amonk这是一种会引入错误的假设。当然:你可以这样假设,但是如果你在写一个列表的时候,在某个时候把178和17打错了,你很容易在不知道的情况下结束,在这种情况下,如果你不检查,你可能会得到错误的结果。与其说抱歉,不如说安全,并提出一个异常,尤其是在这样的情况下,检查条件是计算的一部分,因此基本上不会有性能损失。@D8Amonk:欢迎您随时自我回答:-但也要涵盖“为什么我的函数失败”的情况;你是为有同样问题的人写的。@Bakuriu:因为这是一个编码挑战,我认为代码可以假定只有一个异常值。@MartijnPieters然而问题和答案不仅对OP有用。其他人可能必须解决同样的问题,但在现实生活中,在这种情况下,更好的解决方案是处理错误情况的解决方案。列表理解不是这里的最佳解决方案,不是。尝试用检查的最少元素数来解决它。如果前两个元素的类型不同,则使用第三个来打破僵局,否则,迭代直到找到不适合尾部的。@D8Amonk这是一种会引入错误的假设。当然:你可以这样假设,但是如果你在写一个列表的时候,在某个时候把178和17打错了,你很容易在不知道的情况下结束,在这种情况下,如果你不检查,你可能会得到错误的结果。与其说抱歉,不如说安全,并提出一个异常,尤其是在这样的情况下,检查条件是计算的一部分,因此基本上不会有性能损失。@D8Amonk:欢迎您随时自我回答:-但也要涵盖“为什么我的函数失败”的情况;你写这篇文章是为了那些有着相同p
问题。@Bakuriu:由于这是一个编码挑战,我认为代码可以假定只有一个异常值。@MartijnPieters然而,问题和答案不仅对OP有用。其他人可能必须解决相同的问题,但在现实生活中,在这种情况下,更好的解决方案是处理错误案例的解决方案。@MartijnPieters这是投票最多的解决方案。当我写我的时,我没有看到它,但它增加了我的困惑,为什么我的不工作,因为它似乎使用了我尝试的相同的列表comp逻辑…这将列表分成两部分,并使用len来比较哪一个更短。您的代码假设其中一个为空,这是错误的假设。请注意,这必须处理输入列表中的所有值。两次Mine只需处理列表,直到发现异常。这可能与前3个元素一样小。用[1,3,4]+listrange5,1000000,2来试试这个。我注意到这可能是codewars的最热门投票,但是评论显示这确实不应该是最热门的。从说明输入可能很大的描述来看,这真的很昂贵。@MartijnPieters我开始理解使用迭代器的原因…仍然在吸收关于OP评论的争论…@MartijnPieters这是投票最多的解决方案。当我写我的时,我没有看到它,但它增加了我的困惑,为什么我的不工作,因为它似乎使用了我尝试的相同的列表comp逻辑…这将列表分成两部分,并使用len来比较哪一个更短。您的代码假设其中一个为空,这是错误的假设。请注意,这必须处理输入列表中的所有值。两次Mine只需处理列表,直到发现异常。这可能与前3个元素一样小。用[1,3,4]+listrange5,1000000,2来试试这个。我注意到这可能是codewars的最热门投票,但是评论显示这确实不应该是最热门的。从说明输入可能很大的描述来看,这真的很昂贵。@MartijnPieters我开始理解使用迭代器的原因…仍然在吸收关于OP注释的争论…I for I in_list最好写成Iterinu list,这里不需要使用生成器表达式。您可以将奇偶校验a存储在代码中,并将其用于两个分支。i for i in_list最好写成iterin_list,这里不需要使用生成器表达式。您可以将奇偶校验a存储在代码中,并将其用于两个分支。我已将此提交给了。您能为我指出一个好的方向来理解奇偶校验概念/命名约定吗?@D8Amonk:kata使用相同的术语;这是奇数和偶数的数学定义。参见含义4。我将此提交给了。你能给我指出一个好的方向来理解奇偶校验概念/命名约定吗?@D8Amonk:kata使用相同的术语;这是奇数和偶数的数学定义。见意义4。