将两个列表中的单个项目添加到新列表中

9bfwbjaz  于 2022-10-22  发布在  Python
关注(0)|答案(6)|浏览(173)

编写一个函数,它需要两个整数列表a和b作为参数,并返回一个列表。该函数应按索引合并两个输入列表的元素,并将它们作为元组返回到新列表中。如果一个列表比另一个短,则应尽可能频繁地重复较短列表的最后一个元素。如果一个或两个列表都为空,则应返回空列表。
请考虑以下示例:

merge([0, 1, 2], [5, 6, 7]) # should return [(0, 5), (1, 6), (2, 7)]
merge([2, 1, 0], [5, 6])    # should return [(2, 5), (1, 6), (0, 6)]
merge([], [2, 3])           # should return []

您可以假设参数始终是有效的列表,并且不需要提供任何类型的输入验证。
我的尝试:

def merge(a, b):
    if len(a) == 0 or len(b) == 0:
        mergelist = []
    elif len(a) > len(b):
        for i in range(0, len(b)):
            mergelist = [a[i], b[i]]
        for i in range(len(b), len(a)):
            mergelist = [a[i], b[len(b)]]
    elif len(b) > len(a):
        for i in range(0, len(a)):
            mergelist = [a[i], b[i]]
        for i in range(len(a), len(b)):
            mergelist = [a[len(a)], b[i]]

    return mergelist

print(merge([0, 1, 2], [5, 6]))

有人能告诉我为什么我的代码是错的吗?我的IDE说
列表索引超出范围
但我反复检查了一遍,我想不是。

qnakjoqk

qnakjoqk1#

您的代码中有一些内容需要更新:
(1) 将此格式mergelist = [a[i], b[i]]更改为mergelist.append((a[i], b[i]))
(2) 当len(a)==len(b)
(3) 列表索引超出范围,因为列表索引以零开头。例如,如果len(a)为2,则范围内允许的索引将仅为0和1。所以2超出范围。
请尝试以下代码:

def merge(a, b):
    mergelist = []
    if len(a) == 0 or len(b) == 0:
        return mergelist
    elif len(a) >= len(b):    #takes care of len(a)==len(b)
        for i in range(0, len(b)):
            mergelist.append((a[i], b[i]))
        for i in range(len(b), len(a)):
            mergelist.append((a[i], b[len(b)-1]))    #index minus 1
    elif len(b) > len(a):
        for i in range(0, len(a)):
            mergelist.append((a[i], b[i]))
        for i in range(len(a), len(b)):
            mergelist.append((a[len(a)-1], b[i]))    #index minus 1
    return mergelist

print(merge([0, 1, 2], [5, 6]))
print(merge([5, 6], [0, 1, 2]))
print(merge([0, 1, 2], [5, 6, 7])) # should return [(0, 5), (1, 6), (2, 7)]
print(merge([2, 1, 0], [5, 6]))    # should return [(2, 5), (1, 6), (0, 6)]
print(merge([], [2, 3]))           # should return []

输出:

[(0, 5), (1, 6), (2, 6)]
[(5, 0), (6, 1), (6, 2)]
[(0, 5), (1, 6), (2, 7)]
[(2, 5), (1, 6), (0, 6)]
[]
k5hmc34c

k5hmc34c2#

你可以用zip()来解决这个问题

def merge(a,b):
    zipped = list(zip(a,b))

    if a and b:
        if len(a) == len(b):
            return zipped
        else:
            zipped.append((a[-1],b[-1]))
            return zipped
    else:
        return []

print(merge([0, 1, 2], [5, 6]))
print(merge([5, 6], [0, 1, 2]))
print(merge([0, 1, 2], [5, 6, 7])) # should return [(0, 5), (1, 6), (2, 7)]
print(merge([2, 1, 0], [5, 6]))    # should return [(2, 5), (1, 6), (0, 6)]
print(merge([], [2, 3]))           # should return []

# output:

# [(0, 5), (1, 6), (2, 6)]

# [(5, 0), (6, 1), (6, 2)]

# [(0, 5), (1, 6), (2, 7)]

# [(2, 5), (1, 6), (0, 6)]

# []

但如果某些列表比另一个列表长2项或更多项,则此函数将不起作用

am46iovg

am46iovg3#

具有相同功能的更短变体:

def merge(a,b):
  if len(a) == 0 or len(b) == 0:
    return []
  elif len(a) >= len(b):
    b = b + [b[-1]]*(len(a)-len(b))
  else:
    a = a + [a[-1]]*(len(b)-len(a))
  return list(zip(a,b))

print(merge([0, 1, 2], [5, 6]))
print(merge([5, 6], [0, 1, 2]))
print(merge([0, 1, 2], [5, 6, 7]))
print(merge([2, 1, 0], [5, 6]))
print(merge([], [2, 3]))

输出:

[(0, 5), (1, 6), (2, 6)]
[(5, 0), (6, 1), (6, 2)]
[(0, 5), (1, 6), (2, 7)]
[(2, 5), (1, 6), (0, 6)]
[]
bd1hkmkf

bd1hkmkf4#

我不确定您在条件语句中尝试使用for循环做什么,根据经验,我们尽量避免使用循环,尽管有时确实不可避免。
所以,你的代码在这里中断了b[len(b)],因为索引从0开始。让我们举一个例子,你有b=[5,6],5(索引0),6(索引1)&len(b)=2。你明白为什么不能这样做吗?大错特错,我们都去过那里:)
我建议的解决方案:

def merge_unequal_lists(longest_list, shortest_list):
    first_part = [(longest_list[i], shortest_list[i]) for i in 
    range(len(shortest_list))]
    second_part = [(longest_list[i], shortest_list[-1]) for i in 
    range(len(shortest_list), len(longest_list))]
    mergeList = first_part + second_part
    return mergeList

def new_merge(a, b):
    mergelist = []
    if len(a) == 0 or len(b) == 0:
        return mergelist
    if len(a) == len(b):
        mergeList = list(zip(a, b))
    elif len(a) > len(b):
        mergeList = merge_unequal_lists(a, b)
    elif len(b) > len(a):
        mergeList = merge_unequal_lists(b, a)
        return mergeList

有几点,我真的建议您开始使用zip()函数,非常有用,特别是对于您的用例。此外,列表理解比for循环更有效,它们对于任何用例都非常方便。最后,遵循DRY(Don’t Repeat Yourself)原则,我试图不重复自己,因此创建了一个额外的函数,它对您的两个条件(len(a)>len(b)&len(b)>len(a))执行相同的操作。
我希望这有帮助。

4nkexdtk

4nkexdtk5#

此解决方案经过了合理优化,因为它没有在内存中扩展ab

def merge(a, b):
    if not a or not b:
        return []

    merged_list = list(zip(a, b))
    if len(a) < len(b):
        merged_list += [(a[-1], bb) for bb in b[len(a):]]
    elif len(a) > len(b):
        merged_list += [(b[-1], aa) for aa in a[len(b):]]

    return merged_list
dced5bon

dced5bon6#

有人能告诉我为什么我的代码错了吗
b[len(b)]导致问题。改用b[-1]
怎么样

def merge(a,b):
    if len(a) == len(b) or not a or not b: return [ (x, y) for x, y in zip(a, b) ]
    return [ (x, y) for x, y in zip(a + [a[-1]] * (len(b) - len(a)), b) ] if len(a) < len(b) else [ (x, y) for x, y in zip(a, b + [b[-1]] * (len(a) - len(b))) ]


# if [(x,y)] and [(y,x)] are both acceptable result, then we can use this function.

def merge(a,b):
    if len(a) == len(b) or not a or not b: return [ (x, y) for x, y in zip(a, b) ]
    [a, b] = [a, b] if len(a) < len(b) else [b, a]
    return [ (x, y) for x, y in zip(a + [a[-1]] * (len(b) - len(a)), b)]
  • 演示
>>> print(merge([0, 1, 2], [5, 6, 7])) # should return [(0, 5), (1, 6), (2, 7)]
[(0, 5), (1, 6), (2, 7)]
>>> print(merge([2, 1, 0], [5, 6]))    # should return [(2, 5), (1, 6), (0, 6)]
[(2, 5), (1, 6), (0, 6)]
>>> print(merge([], [2, 3]))
[]

相关问题