撰寫一個函式,它需要兩個整數串列 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 說
串列索引超出范圍
但我一遍又一遍地檢查它,它不是,,,我認為。
編輯:我不認為有這么多人會幫助我并給我他們的代碼版本。他們非常有幫助。非常感謝大家!!!
uj5u.com熱心網友回復:
您的代碼中有一些需要更新的內容:
(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)]
[]
uj5u.com熱心網友回復:
我不確定您要在條件陳述句中使用 for 回圈做什么,根據經驗,我們盡量避免使用回圈,盡管有時確實是不可避免的。
因此,您的代碼在 b[len(b)] 處中斷,因為索引從 0 開始。讓我們舉一個例子,您有 b = [5,6], 5 (index 0), 6 (index 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(不要重復自己)原則,我試圖不重復自己,因此創建了一個額外的函式,它對你的兩個條件做同樣的事情,len(a) > len(b) &長度 (b) > 長度 (a)。
我希望這可以幫到你。
uj5u.com熱心網友回復:
該解決方案經過優化,因為它沒有擴展a并且b在記憶體中。
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
uj5u.com熱心網友回復:
你可以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 個或更多項,則此功能將不起作用
uj5u.com熱心網友回復:
執行相同操作的較短變體:
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)]
[]
uj5u.com熱心網友回復:
誰能告訴我為什么我的代碼是錯誤的
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])) []
uj5u.com熱心網友回復:
b[len(b)]超出范圍
并且
a[len(a)]超出范圍
最后一個元素應該是b[len(b)-1]anda[len(a)-1]
或
b[-1]anda[-1]
uj5u.com熱心網友回復:
使用了不同的實作itertools.zip_longest
from itertools import zip_longest
def merge(a, b):
# check if list empty
if not a or not b:
return []
# merging
if len(a) == len(b):
return zip(a, b)
elif len(a) > len(b):
fill_term = b[-1]
else:
fill_term = a[-1]
return list(zip_longest(a, b, fillvalue=fill_term))
l = merge([1, 2, 3], [0, 4])
一個zip免費的實作。使用了串列的淺拷貝。
def merge(a, b):
# check if list empty
if not a or not b:
return []
# normalize the size of list
diff = abs(len(a) - len(b))
if len(a) > len(b):
fill_term = b[-1]
b = b.copy() # shallow copy
b.extend([fill_term]*diff)
elif len(a) < len(b):
fill_term = a[-1]
a = a.copy() # shallow copy
a.extend([fill_term]*diff)
# pairing
return [(a_term, b[i]) for i, a_term in enumerate(a)]
為了避免淺拷貝,list.copy例如b = b [fill_term]*diff,創建一個新串列,對于a
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/519569.html
上一篇:從函式到函式的變數
