如何在 Python 中仅使用递归返回列表的奇数?

发布于 2024-09-29 10:31:43 字数 48 浏览 3 评论 0原文

我不想使用 while 或 for 循环,只想使用递归返回给定列表中的奇数。谢谢!

I do not want to use while or for loops, just want to use recursion to return the odd numbers in a given list. Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

℡Ms空城旧梦 2024-10-06 10:31:43
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:])

不需要额外的变量或参数。

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:])

No extra variables or parameters needed.

醉酒的小男人 2024-10-06 10:31:43
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
def only_odd(L):
    return L[0:L[0]&1]+only_odd(L[1:]) if L else L

This version is much faster as it avoids making copies of 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 []

This one only uses O(log n) stack space

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
梦幻的味道 2024-10-06 10:31:43
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]

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

Here's a test output of what I get when I run this

[7, 5, 3, 1]

跨年 2024-10-06 10:31:43

考虑到 python 中默认的堆栈深度限制为 1000,我真的不会为此使用递归。我知道上面有很多递归实现,所以这里有一个以 python 方式实现的非递归实现

print filter(lambda x: x % 2, range(0, 10))

:如果你真的必须使用递归,这是我的尝试。这与乔什·马修斯的版本非常相似。

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))

Considering the default stack depth limit of 1000 in python, I would really not use recursion for this. I know there are a lot of recursive implementations above so here's a non-recursive one that is doing it the python way:

print filter(lambda x: x % 2, range(0, 10))

And for the sake of completeness; if you really really must use recursion here's my go at it. This is very similar to the version by 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))
无力看清 2024-10-06 10:31:43

这是另一种方法,它返回奇数列表,而不是修改传入的列表。与 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]

Here's another way of doing it which returns the list of odd numbers rather than modifying the list passed in. Very similar to that provided by GWW but I thought I'd add it for completeness.

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],[])

Output is:

[1, 3, 5, 7, 9]
追我者格杀勿论 2024-10-06 10:31:43

由于这是一个聚会,我只是想提出一个好的、合理的、真正的程序员TM解决方案。它是用 emacs 编写的,灵感来自 gnibbler 的答案。与他一样,它使用 &1 而不是 % 2 (如果 1 已经存在,则将 2 添加到 co_consts 中是纯粹的颓废)并使用它仅当第一个元素奇数时才获取第一个元素的巧妙技巧,但减少了一些周期,节省了大约 5% 的时间(在我的机器上,在 linux2 内核上运行用 GCC 4.4.3 编译的 2.6.5)。

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())

Since it's a party, I just thought I'd chime in with a nice, sensible, Real ProgrammerTM solution. It's written in emacs and inspired by gnibbler's answer. Like his, it uses &1 instead of % 2 (adding 2 into co_consts is pure decadence if 1 is already there) and uses that nifty trick for getting the first element only if it's odd, but shaves some cycles off for a time savings of around 5% (on my machine, running 2.6.5 compiled with GCC 4.4.3 on a linux2 kernel).

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())
我家小可爱 2024-10-06 10:31:43
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]
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]
笑脸一如从前 2024-10-06 10:31:43
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:])
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:])
櫻之舞 2024-10-06 10:31:43
>>> 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]
>>>
>>> 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
>>>

This one avoids the list copying overhead, at the cost of getting the answer backwards and a big increase in the ugliness factor:

>>> 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]
>>>
笑咖 2024-10-06 10:31:43

好吧,因为我们都在做出贡献:

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 []

well since we're all contributing:

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 []
风筝有风,海豚有海 2024-10-06 10:31:43

好吧,还有很多其他答案,但我认为我的答案是最干净的:

def odds(L):
   if not L: 
      return []
   return [L[0]] * (L[0] % 2) + odds(L[1:])

有趣的练习,但只是重申一下,在实践中永远不要递归地执行此操作。

Well, there are a bunch of other answers but I think mine's the cleanest:

def odds(L):
   if not L: 
      return []
   return [L[0]] * (L[0] % 2) + odds(L[1:])

Fun exercise but just to reiterate, don't ever do this recursively in practice.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文