使用递归从两个列表中创建配对列表

时间:2019-12-15 14:16:39

标签: python list recursion tuples

我需要创建一个将两个列表作为参数并使用python 3.x中的递归返回两个列表中的元素对列表的函数。

输入create_all_pairs([1,2], [3,4])应该给我:

[(1,3), (1,4), (2,3), (2,4)]

我已经通过3种不同的方式创建了此函数:使用for循环,使用while循环和使用列表理解。

def create_all_pairs_for(xs, ys):
    lst = []
    for x in xs:
        for y in ys:
            lst.append((x,y))
    return lst
def create_all_pairs_while(xs, ys):
    lst = []
    xscount = 0
    yscount = 0
    while xscount < len(xs):
        while yscount < len(ys):
            lst.append((xs[xscount], ys[yscount]))
            yscount += 1
        xscount += 1
        yscount = 0
    return lst
def create_all_pairs_listcomp(xs, ys):
    lst = [(a,b) for a in xs for b in ys]
    return lst

如何使用递归编写此函数?这是我到目前为止所获得的,但是我感到完全迷失了。

def create_all_pairs_rec(xs, ys):
    if not xs:
        return []
    else:
        return list(map(create_all_pairs_rec(xs, ys)), ys)

5 个答案:

答案 0 :(得分:3)

以下将是递归实现:

def create_all_pairs(xs, ys):
    if not (xs and ys):
        return []
    return [(xs[0], y) for y in ys] + create_all_pairs(xs[1:], ys)

虽然这有点作弊,因为它仅使用递归来减少xs,但是这是一个真正的递归除法解决方案,它递归地减小了xsys

def create_all_pairs(xs, ys):
    if not (xs and ys):  # base case 1: any empty list
        return []
    if len(xs) == len(ys) == 1:  # base case 2: two singleton lists
        return [(xs[0], ys[0])]
    mid_x, mid_y = len(xs) // 2, len(ys) // 2
    return create_all_pairs(xs[:mid_x], ys[:mid_y]) + create_all_pairs(xs[:mid_x], ys[mid_y:]) + \
           create_all_pairs(xs[mid_x:], ys[:mid_y]) + create_all_pairs(xs[mid_x:], ys[mid_y:])

>>> create_all_pairs([1, 2], [3, 4])
[(1, 3), (1, 4), (2, 3), (2, 4)]
>>> create_all_pairs([1, 2, 3], [3, 4, 5])
[(1, 3), (1, 4), (1, 5), (2, 3), (3, 3), (2, 4), (2, 5), (3, 4), (3, 5)]

答案 1 :(得分:0)

find_all_pairs(xs,ys,ret):
    if xs == []: #basecase
        return ret #return the list we built
    else:
        left = xs.pop() #we take an element out of the left list
        for right in ys: #for every element in the right list
            ret.append((left,right)) #we append to the list were building a (left,right) tuple
         return find_all_pairs(xs,ys,ret) #call the function again with the decremented xs and the appended ret

答案 2 :(得分:0)

所有对与笛卡尔乘积相同。

对于使用递归来计算笛卡尔乘积:Cross product of sets using recursion(我们有很好的解释),我们可以对此答案进行修改

此功能的优点是它适用于任意数量的列表(即1、2、3等)。

def create_all_pairs(*seqs):
    if not seqs:
        return [[]]
    else:
        return [[x] + p for x in seqs[0] for p in create_all_pairs(*seqs[1:])]

print(create_all_pairs([1,2], [3,4]))

输出

[[1, 3], [1, 4], [2, 3], [2, 4]]

答案 3 :(得分:0)

另一种递归实现,与上面的答案相比,该实现还以更连续的顺序将条目添加到最终对对中:

def create_all_pairs(list1, list2, resulting_list, index1=0, index2=0):

    if index1 < len(list1) and index2 < (len(list2)-1):
        resulting_list.insert(0, create_all_pairs(list1, list2, resulting_list, index1, index2+1))

    elif index1 < (len(list1)-1) and index2 >= (len(list2)-1):
        resulting_list.insert(0, create_all_pairs(list1, list2, resulting_list, index1+1, 0))

    if index1 == 0 and index2 == 0:
        resulting_list.insert(0, (list1[index1], list2[index2]))

    return (list1[index1], list2[index2])

resulting_list = list()
create_all_pairs([1, 2, 3], [3, 4, 5], resulting_list)

print("Resulting list is:", resulting_list)

结果:

Resulting list is: [(1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 3), (3, 4), (3, 5)]

答案 4 :(得分:0)

def all_pairs(x, y):
    return x and y and [(x[0], y[0])] + all_pairs(x[:1], y[1:]) + all_pairs(x[1:], y)

基于@schwobaseggl的“真正的递归”解决方案,只是拆分方式不同。