这是我的家庭作业的一部分,我接近最后的答案,但尚未完成。我需要编写一个计算列表中奇数的函数。
创建一个递归函数count_odd(l),它将唯一参数作为整数列表。该函数将返回奇数列表元素数的计数,即不能被2整除。\
>>> print count_odd([])
0
>>> print count_odd([1, 3, 5])
3
>>> print count_odd([2, 4, 6])
0
>>> print count_odd([0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144])
8
这是我到目前为止所拥有的: # - 递归函数count_odd - #
def count_odd(l):
"""returns a count of the odd integers in l.
PRE: l is a list of integers.
POST: l is unchanged."""
count_odd=0
while count_odd<len(l):
if l[count_odd]%2==0:
count_odd=count_odd
else:
l[count_odd]%2!=0
count_odd=count_odd+1
return count_odd
#- test harness
print count_odd([])
print count_odd([1, 3, 5])
print count_odd([2, 4, 6])
print count_odd([0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144])
你可以帮我解释一下我失踪了什么。前两个测试工具工作正常,但我不能得到最后两个。谢谢!
答案 0 :(得分:4)
由于这是作业,请考虑这个只计算列表的伪代码:
function count (LIST)
if LIST has more items
// recursive case.
// Add one for the current item we are counting,
// and call count() again to process the *remaining* items.
remaining = everything in LIST except the first item
return 1 + count(remaining)
else
// base case -- what "ends" the recursion
// If an item is removed each time, the list will eventually be empty.
return 0
这与作业所要求的非常类似,但它需要转换为Python,你必须找出正确的递归案例逻辑。
快乐的编码。
答案 1 :(得分:2)
def count_odd(L):
return (L[0]%2) + count_odd(L[1:]) if L else 0
答案 2 :(得分:1)
切片好吗?对我来说不“感觉”递归,但我想整个事情都与普通的习语有关(即 - 在python中这种递归)
def countOdd(l):
if l == list(): return 0 //base case, empty list means we're done
return l[0] % 2 + countOdd(l[1:]) //add 1 (or don't) depending on odd/even of element 0. recurse on the rest
x%2对于赔率为1,对于均衡为0。如果您对此感到不舒服或者只是不明白,请使用以下内容代替上面的最后一行
thisElement = l[0]
restOfList = l[1:]
if thisElement % 2 == 0: currentElementOdd = 0
else: currentElementOdd = 1
return currentElementOdd + countOdd(restOfList)
PS - 这是非常递归的,如果你把它转到= P
,看看老师说的话>>> def countOdd(l):
... return fold(lambda x,y: x+(y&1),l,0)
...
>>> def fold(f,l,a):
... if l == list(): return a
... return fold(f,l[1:],f(a,l[0]))
答案 3 :(得分:1)
所有先前的答案都将问题细分为大小为1和大小为n-1的子问题。有几个人注意到递归堆栈可能很容易爆炸。此解决方案应将递归堆栈大小保持为O(log n):
def count_odd(series):
l = len(series) >> 1
if l < 1:
return series[0] & 1 if series else 0
else:
return count_odd(series[:l]) + count_odd(series[l:])
答案 4 :(得分:0)
递归的目标是将问题分成更小的部分,并将解决方案应用于较小的部分。在这种情况下,我们可以检查列表的第一个数字(l[0]
)是否为奇数,然后再次调用该函数(这是“递归”)与列表的其余部分(l[1:]
) ,将我们当前的结果添加到递归的结果中。
答案 5 :(得分:0)
def count_odd(series):
if not series:
return 0
else:
left, right = series[0], series[1:]
return count_odd(right) + (1 if (left & 1) else 0)
答案 6 :(得分:0)
def count_odd(integers):
def iter_(lst, count):
return iter_(rest(lst), count + is_odd(first(lst))) if lst else count
return iter_(integers, 0)
def is_odd(integer):
"""Whether the `integer` is odd."""
return integer % 2 != 0 # or `return integer & 1`
def first(lst):
"""Get the first element from the `lst` list.
Return `None` if there are no elements.
"""
return lst[0] if lst else None
def rest(lst):
"""Return `lst` list without the first element."""
return lst[1:]
Python中没有尾调用优化,所以上面的版本纯粹是教育性的。
可以将调用视为:
count_odd([1,2,3]) # returns
iter_([1,2,3], 0) # could be replaced by; depth=1
iter_([2,3], 0 + is_odd(1)) if [1,2,3] else 0 # `bool([1,2,3])` is True in Python
iter_([2,3], 0 + True) # `True == 1` in Python
iter_([2,3], 1) # depth=2
iter_([3], 1 + is_odd(2)) if [2,3] else 1
iter_([3], 1 + False) # `False == 0` in Python
iter_([3], 1) # depth=3
iter_([], 1 + is_odd(3)) if [3] else 1
iter_([], 2) # depth=4
iter_(rest([]), 2 + is_odd(first([])) if [] else 2 # bool([]) is False in Python
2 # the answer
为避免大数组的“超出最大递归深度”错误,递归函数中的所有尾调用都可以包含在lambda:
表达式中;并且可以使用特殊的trampoline()
函数来展开这些表达式。它有效地将递归转换为在简单循环上迭代:
import functools
def trampoline(function):
"""Resolve delayed calls."""
@functools.wraps(function)
def wrapper(*args):
f = function(*args)
while callable(f):
f = f()
return f
return wrapper
def iter_(lst, count):
#NOTE: added `lambda:` before the tail call
return (lambda:iter_(rest(lst), count+is_odd(first(lst)))) if lst else count
@trampoline
def count_odd(integers):
return iter_(integers, 0)
示例:
count_odd([1,2,3])
iter_([1,2,3], 0) # returns callable
lambda:iter_(rest(lst), count+is_odd(first(lst))) # f = f()
iter_([2,3], 0+is_odd(1)) # returns callable
lambda:iter_(rest(lst), count+is_odd(first(lst))) # f = f()
iter_([3], 1+is_odd(2)) # returns callable
lambda:iter_(rest(lst), count+is_odd(first(lst))) # f = f()
iter_([], 1+is_odd(3))
2 # callable(2) is False
答案 7 :(得分:0)
我会这样写:
def countOddNumbers(numbers):
sum = 0
for num in numbers:
if num%2!=0:
sum += numbers.count(num)
return sum
答案 8 :(得分:0)
不确定我是否有你的问题,但如上所述:
def countOddNumbers(numbers):
count=0
for i in numbers:
if i%2!=0:
count+=1
return count
答案 9 :(得分:-1)
生成器可以在一行代码中快速生成结果:
sum((x%2 for x in nums))