#python #list #merge #tuples
Вопрос:
Правила: Если один список короче другого, последний элемент более короткого списка следует повторять так часто, как это необходимо. Если один или оба списка пусты, должен быть возвращен пустой список.
слияние([0, 1, 2], [5, 6, 7])
должен вернуться [(0, 5), (1, 6), (2, 7)]
слияние([2, 1, 0], [5, 6])
должен вернуться [(2, 5), (1, 6), (0, 6)]
слияние([ ], [2, 3])
должен вернуться []
это то, что я написал до сих пор
def merge(a, b):
mergelist = []
for pair in zip(a, b):
for item in pair :
mergelist.append(item )
return mergelist
печать (слияние([0, 1, 2], [5, 6]))
Комментарии:
1. Используйте встроенную функцию zip
2. Вам нужно просто
list(zip(a, b))
?3.
zip
уже в его коде. и ожидаемые результаты немного странные4. Итак, вы ожидаете, что выходные данные будут иметь длину первого списка, а последний элемент второго списка будет повторяться, если он короче? Что, если он пуст? Или это что-то еще? Пожалуйста, уточните правила.
5. Если один список короче другого, последний элемент более короткого списка следует повторять так часто, как это необходимо. Если один или оба списка пусты, должен быть возвращен пустой список.
Ответ №1:
Спасибо, что задали вопрос. Я попытался внести изменения в ваш код, поскольку всегда легче понять наш собственный код. Пожалуйста, найдите изменения
def merge(a, b):
mergelist = []
if not a or not b:
return []
elif len(a) > len(b):
occ = len(a)-len(b)
b.extend([b[len(b)-1] for i in range(occ)])
elif len(a) < len(b):
occ = len(b)-len(a)
a.extend([a[len(a)-1] for i in range(occ)])
for pair in zip(a, b):
mergelist.append(pair)
return mergelist
print(merge(l,l1))
Ответ №2:
Вам нужно вручную добавить каждый кортеж в возвращаемый список, так как вам нужно проверить, соответствует ли длина второго списка соответствующей. Это один из способов решения этой проблемы
def merge(l1, l2):
new = []
for i in range(len(l1)):
if i > len(l2)-1:
s2 = l2[len(l2)-1] # use the last element of second list if there are no more elements
else:
s2 = l2[i]
new.append(l1[i], s2)
return new
"""
>>> merge([0,1,2],[5,6,7])
[(0, 5), (1, 6), (2, 7)]
>>> merge([2,1,0],[5,6])
[(2, 5), (1, 6), (0, 6)]
>>> merge([],[2,3])
[]
"""
Ответ №3:
На самом деле это несколько сложно. Можно подумать, что сработает что-то простое, подобное этому:
def merge(a, b):
# use iterator to keep iterations state after zip
a, b = iter(a), iter(b)
rtrn = list(zip(a, b))
try:
taila, tailb = rtrn[-1]
except IndexError: # one or both empty
return rtrn
# only one of these loops will run, draining the longer input list
rtrn.extend((ai, tailb) for ai in a)
rtrn.extend((taila, bi) for bi in b)
return rtrn
Здесь хитрость заключается в использовании итератора, а не итерируемого. Итератор сохраняет свое состояние. Таким образом, после zip оба итератора все равно должны указывать на место, где zip остановился.
Однако это не работает, если b — более короткий список. Потому что тогда zip удалит одно значение из a и отбросит его. Вы должны быть осторожны, чтобы избежать этого.
Самый простой способ — просто материализовать два списка и явно разобраться с различиями в длине.
def merge(a, b):
# ensure that we have lists, not anything else like iterators, sets, etc
a, b = list(a), list(b)
rtrn = list(zip(a, b))
try:
taila, tailb = rtrn[-1]
except IndexError: # one or both empty
return rtrn
rtrnlen = len(rtrn)
# only one of these loops will run, draining the longer input list
# You could also use itertools.zip_longest for this
rtrn.extend((ai, tailb) for ai in a[rtrnlen:])
rtrn.extend((taila, bi) for bi in b[rtrnlen:])
return rtrn
Ответ №4:
Я бы использовал zip_longest
:
from itertools import zip_longest
def merge(a, b):
return list(a and b and zip_longest(a, b, fillvalue=min(a, b, key=len)[-1]))
То же самое, другой стиль:
def merge(a, b):
if a and b:
short = min(a, b, key=len)
return list(zip_longest(a, b, fillvalue=short[-1]))
return []
Ответ №5:
from itertools import zip_longest
def merge(a,b):
if len(a) > len(b):
return list((zip_longest(a,b,fillvalue=b[-1])))
else:
return list((zip_longest(a,b,fillvalue=a[-1])))`
например
a = [2,3,5]
b = [1,2]
merge(a,b)
[(2, 1), (3, 2), (5, 2)]
Ссылка на документацию для zip_longest
https://docs.python.org/3/library/itertools.html#itertools.zip_longest
Комментарии:
1. слияние (a, b) должно возвращать [(2, 1), (3, 2), (5, 2)]
2. @newbie я исправил код для этого условия