简体   繁体   English

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

[英]Create a list of pairs from two lists using recursion

I need to create a function that takes two lists as arguments and returns a list of the pairs of the elements in the two lists using recursion in python 3.x.我需要创建一个函数,该函数将两个列表作为参数,并使用 python 3.x 中的递归返回两个列表中元素对的列表。

The input create_all_pairs([1,2], [3,4]) should give me :输入create_all_pairs([1,2], [3,4])应该给我:

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

I have created this function in 3 differen ways: using for-loops, using while-loops and using list comprehension.我以 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

How can i write this function using recursion?如何使用递归编写此函数? This is what i have got so far, but i feel completely lost.这是我到目前为止所得到的,但我觉得完全迷失了。

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

The following would be a recursive implementation:以下将是递归实现:

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)

While this is a bit of cheat, as it only uses recursion to reduce the xs , here is a true recursive divide'n'conquer solution that decreases the problem size recursively for both xs and 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)]
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

All pairs is the same as the cartesion product.所有对都与 cartesion 产品相同。

We can adapt this answer for using recursion to compute cartesion product: Cross product of sets using recursion (which has a good explanation)我们可以调整这个答案以使用递归来计算笛卡尔积: 使用递归的集合的交叉乘积(有很好的解释)

An advantage of this function is that it works for an arbitrary number of lists (ie 1, 2, 3, etc.).此函数的一个优点是它适用于任意数量的列表(即 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]))

Output输出

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

Another recursive implementation, which also adds entries in a more sequential order to the final list of pairs, as compared to the answer above:另一个递归实现,与上面的答案相比,它还以更连续的顺序将条目添加到最终的对列表中:

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)

Result:结果:

Resulting list is: [(1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 3), (3, 4), (3, 5)]
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)

Based on @schwobaseggl's "true recursive" solution, just splitting differently.基于@schwobaseggl 的“真正递归”解决方案,只是拆分方式不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM