我在Python中编写一个简单的程序,必须合并两个列表。我从算法分析导论中采用了以下伪代码。
现在我已经用Python编写了以下程序。
def merge_list(a,b):
a,b = sorted(a),sorted(b)
p1,p2,i = 0,0,0 #python indices start from 0
c = [0 for x in range(len(a)+len(b))]
while i<(len(a)+len(b)):
if a[p1] <= b[p2]:
c[i] = a[p1]
p1 = p1 + 1
else:
c[i] = b[p1]
p2 = p2 + 1
i += 1
return c
res = merge_list([1,3,5],[2,4,6])
现在我收到错误 IndexError:列表索引超出范围。 请纠正我在这里做错了什么?
答案 0 :(得分:4)
正如其他人所指出的,你混淆了p1
和p2
。但是您还必须检查空列表,并且还必须考虑输入长度不同的可能性。此算法未列出其所有前提条件,即n
必须小于或等于m
才能使其按写入方式工作。所以,让我们来处理。
>>> def merge_list(a,b):
a,b = sorted(a),sorted(b)
if len(a) > len(b):
a,b = b,a
p1,p2,i = 0,0,0 #python indices start from 0
c = [0 for x in range(len(a)+len(b))]
while i<(len(a)+len(b)):
if p1<len(a) and p2<len(b) and a[p1] <= b[p2]:
c[i] = a[p1]
p1 = p1 + 1
elif p2<len(b):
c[i] = b[p2]
p2 = p2 + 1
i += 1
return c
>>> merge_list([1,3,5,7,9],[2,4,6,8])
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> merge_list([1,3,5],[2,4,6,7])
[1, 2, 3, 4, 5, 6, 7]
此修订版的前三行并非严格来自伪代码,但除此之外,这是与伪代码的1对1配对。
请注意,Sabyasachi的答案更多是pythonic,通常是首选。
答案 1 :(得分:3)
错字。在else语句之后,使用p1索引b
else:
c[i] = b[p1]
p2 = p2 + 1
应该是:
else:
c[i] = b[p2]
p2 = p2 + 1
再次查看此问题,您还需要从Aaron的答案中进行长度检查。
答案 2 :(得分:3)
该代码看起来并不是非常pythonic。做这样的事情。
def merge(a,b):
c=[]
while a and b:
if a[0]<b[0]:
c+=a[:1]
a=a[1:]
else:
c+=b[:1]
b=b[1:]
return c+a+b
解释:它会创建一个新列表c。而a和b检查a和b是否都有元素。然后它检查哪个第一个元素较小并将其添加到c(注意a[:1]
等同于[a[0]]
并通过重新分配从原始列表中删除元素。最后当它出来时循环,其中一个列表是空的,所以返回实际上要么返回c + a或c + b,这非常直观地说你会期望合并返回。
答案 3 :(得分:2)
您将p1
增加到a
的范围之外。
如果您已经到达其中一个列表的末尾,则需要检查。
def merge_list(a,b):
a,b = sorted(a),sorted(b)
p1,p2,i = 0,0,0 #python indices start from 0
c = []
# first two conditions here are implied.
while p1 < len(a) and p2 < len(b) and i < (len(a)+len(b)):
if a[p1] <= b[p2]:
c.append(a[p1])
p1 += 1
else:
c.append(b[p2])
p2 += 1
if p1 >= len(a): # implied
while p2 < len(b):
c.append(b[p2])
p2 += 1
i += 1
if p2 >= len(b): # implied
while p1 < len(a):
c.append(a[p1])
p1 += 1
i += 1
i += 1
return c
res = merge_list([1,3,5,7],[2,4,6,8,10])
print res
打印
[1, 2, 3, 4, 5, 6, 7, 8, 10]