我不想使用while或for循环,只想使用递归来返回给定列表中的奇数。谢谢!
答案 0 :(得分:9)
def find_odds(numbers):
if not numbers:
return []
if numbers[0] % 2 == 1:
return [numbers[0]] + find_odds(numbers[1:])
return find_odds(numbers[1:])
无需额外的变量或参数。
答案 1 :(得分:7)
def only_odd(L):
return L[0:L[0]&1]+only_odd(L[1:]) if L else L
这个版本要快得多,因为它避免复制L
def only_odd_no_copy(L, i=0):
return L[i:i+(L[i]&1)]+only_odd_no_copy(L, i+1) if i<len(L) else []
这个只使用O(log n)堆栈空间
def only_odd_logn(L):
x=len(L)/2+1
return L[:L[0]&1] + only_odd2(L[1:x]) + only_odd_logn(L[x:]) if L else L
答案 2 :(得分:3)
def find_odds(numbers, odds):
if len(numbers) == 0:
return
v = numbers.pop()
if v % 2 == 1:
odds.append(v)
find_odds(numbers, odds)
odds = []
numbers = [1,2,3,4,5,6,7]
find_odds(numbers,odds)
# Now odds has the odd numbers
print odds
这是我运行时得到的测试结果
[7,5,3,1]
答案 3 :(得分:3)
考虑到python中默认的堆栈深度限制为1000,我真的不会使用递归。我知道上面有很多递归实现,所以这里是一个非递归的实现,它以python的方式进行:
print filter(lambda x: x % 2, range(0, 10))
为了完整起见;如果你真的必须在这里使用递归,那么我就去吧。这与Josh Matthews的版本非常相似。
def rec_foo(list):
if not list:
return []
return ([list[0]] if list[0] % 2 else []) + rec_foo(list[1:])
print rec_foo(range(1, 10))
答案 4 :(得分:2)
这是另一种方法,它返回奇数列表而不是修改传入的列表。非常类似于GWW
提供的但是我认为我会添加它以保证完整性。
def find_odds(numbers, odds):
if len(numbers) == 0:
return odds
if numbers[0] % 2 == 1:
odds.append(numbers[0])
return find_odds(numbers[1:],odds)
print find_odds([1,2,3,4,5,6,7,8,9],[])
输出是:
[1, 3, 5, 7, 9]
答案 5 :(得分:2)
因为它是一个派对,我只是想我会用一个好的,明智的,真正的程序员 TM 解决方案。它是用emacs编写的,灵感来自gnibbler的答案。和他一样,它使用&1
代替% 2
(如果已经存在1,则将co_consts
中的2添加为纯粹的颓废)并且仅当它是奇数时才使用那个漂亮的技巧来获取第一个元素,但是节省了一些时间,节省了大约5%的时间(在我的机器上,运行2.6.5在Linux2内核上使用GCC 4.4.3编译)。
from opcode import opmap
import types
opcodes = [opmap['LOAD_FAST'], 0,0, # L
opmap['JUMP_IF_FALSE'], 24,0,
opmap['DUP_TOP'],
opmap['LOAD_CONST'], 0,0, # 0
opmap['BINARY_SUBSCR'],
opmap['LOAD_CONST'], 1,0, # 1
opmap['BINARY_AND'],
opmap['SLICE+2'],
opmap['LOAD_GLOBAL'], 0,0, # odds
opmap['LOAD_FAST'], 0,0,
opmap['LOAD_CONST'], 1,0,
opmap['SLICE+1'],
opmap['CALL_FUNCTION'], 1,0,
opmap['BINARY_ADD'],
opmap['RETURN_VALUE']]
code_str = ''.join(chr(byte) for byte in opcodes)
code = types.CodeType(1, 1, 4, 0x1 | 0x2 | 0x40, code_str, (0, 1),
('odds',), ('L',), '<nowhere>', 'odds',
0, '')
odds = types.FunctionType(code, globals())
答案 6 :(得分:1)
odds = []
def findOdds(listOfNumbers):
if listOfNumbers[0] % 2 == 1:
odds.append(listOfNumbers[0])
if len(listOfNumbers) > 1:
findOdds(listOfNumbers[1:])
findOdds(range(0,10))
print odds
# returns [1,3,5,7,9]
答案 7 :(得分:0)
>>> def fodds(alist, odds=None):
... if odds is None: odds = []
... if not alist: return odds
... x = alist[0] # doesn't destroy the input sequence
... if x % 2: odds.append(x)
... return fodds(alist[1:], odds)
...
>>> fodds(range(10)) # only one arg needs to be supplied
[1, 3, 5, 7, 9] # same order as input
>>>
这个避免了列表复制开销,但代价是向后获得答案并且丑陋因素大幅增加:
>>> def fo(aseq, pos=None, odds=None):
... if odds is None: odds = []
... if pos is None: pos = len(aseq) - 1
... if pos < 0: return odds
... x = aseq[pos]
... if x % 2: odds.append(x)
... return fo(aseq, pos - 1, odds)
...
>>> fo(range(10))
[9, 7, 5, 3, 1]
>>>
答案 8 :(得分:0)
def odds(L):
if L == []:
return []
else:
if L[0]%2:
B = odds(L[1:])
B.append(L[0])
return B
else:
return odds(L[1:])
答案 9 :(得分:0)
嗯,还有很多其他的答案,但我认为我的最干净:
def odds(L):
if not L:
return []
return [L[0]] * (L[0] % 2) + odds(L[1:])
有趣的运动,但只是重申,不要在实践中递归地进行。
答案 10 :(得分:0)
因为我们都在做出贡献:
def odds(aList):
from operator import lshift as l
if aList and not aList[1:]:
return aList if aList[-1] - l(aList[0]>>1, 1) else list()
return odds(aList[:len(aList)/3+1]) + odds(aList \
[len(aList)/3+1:]) if aList else []