如何重写此递归函数以生成具有 yield 的生成器?

How to rewrite this recursive function to produce a generator with yield?

我很难理解如何在递归函数中使用 yield。甚至有可能,还是我必须重写函数以使其迭代才能使用 yield?

def extract_pairs(li, return_list):
    if len(li) == 2 and type(li[0]) != list:
        return_list.append(li)
        return

    for item in li:
        extract_pairs(item, return_list)

ret = []
extract_pairs([1, 1], ret)
print(ret) #[[1, 1]]

ret = []
extract_pairs([[1, 1], [2, 2]], ret)
print(ret) # [[1, 1], [2, 2]]

ret = []
extract_pairs([[[1, 1]], [2, 2], []], ret)
print(ret) # [[1, 1], [2, 2]]

我不确定你为什么要将生成器累加到一个引用中。无论如何,我已经提供了三种解决方案,一种是迭代的,一种是递归的,一种是使用引用的递归。

def is_pair(li):
    return len(li) == 2 and type(li[0]) != list

# Pretty much what you did, except we don't use a ref
def extract_pairs(li):
    for item in li:
        if is_pair(item):
            yield item

# If the list is empty, then terminate the generator
# otherwise yield if the head of the list is a pair
# then, recurse on the tail of the list
def extract_pairs_rec(li):
    if li == []:
        return
    elif is_pair(li[0]):
        yield li[0]
    
    yield from extract_pairs_rec(li[1:])

# This is pretty much what we did above,
# except that we append to the reference instead of `yield`ing
def extract_pairs_rec_by_ref(li, ref):
    if li == []:
        return
    elif is_pair(li[0]):
        ref.append(li[0])

    yield from extract_pairs_rec_by_ref(li[1:], ref)
print(list(extract_pairs([[1, 1], [], [2,2], []])))

ref = []
list(extract_pairs_rec_by_ref([[1, 1], [], [2,2], []], ref))
print(ref)

print(list(extract_pairs_rec([[1, 1], [], [2,2], []])))

# All of them is then equal to
# [[1, 1], [2, 2]]