我尝试了一个可以删除列表中两个相邻重复项的函数。删除任何新的重复对,该功能将继续进行,直到列表中没有更多重复对为止。
我遇到一个问题,即一旦我有了一个没有相邻重复项的列表,该如何告诉该函数停止。
def removepair(no):
i = 1
if len(no) == 0 or len(no) == 1:
return no
while i < len(no):
if no[i] == no[i-1]:
no.pop(i)
no.pop(i-1)
i -= 1
i += 1
return removepair(no)
到目前为止,该函数在删除后将返回0或单个元素:
输入:[1、2、2、1]输出:[]
或
输入:[4,4,4,4,4]输出:[4]
但是问题是,一旦它具有一个包含多个元素的列表,我不知道如何停止递归函数:
输入:[1,2,3,3,2,1,5,6,7]
预期输出:[5,6,7]
答案 0 :(得分:1)
如果我们仔细地设置递归,我们也许可以避免布尔标志和计数器:
def removepairs(numbers):
if not numbers: # base case #1, empty
return numbers
first, *second_on = numbers
if not second_on: # base case #2, one element
return numbers
second, *third_on = second_on
if first == second:
return removepairs(third_on)
result = [first] + removepairs(second_on)
if result == numbers:
return numbers # base case #3, no change!
return removepairs(result)
print(removepairs([1, 2, 3, 3, 2, 1, 5, 6, 7]))
输出
> python3 test.py
[5, 6, 7]
>
答案 1 :(得分:1)
如果不需要递归函数,则可以使用以下代码轻松完成。我已经评论了印刷声明。
def removepair(input_list):
unique_input_list = list(set(input_list))
output_list = list(x for x in unique_input_list if input_list.count(x)%2 == 1)
#print('Input List: ', input_list)
#print('Output list: ', output_list)
return output_list
Input List: [1, 2, 3, 3, 2, 1, 5, 6, 7]
Output list: [5, 6, 7]
Input List: [4, 4, 4, 4, 4]
Output list: [4]
Input List: [1, 2, 3, 3, 2, 1]
Output list: []
答案 2 :(得分:1)
当没有元素从列表中弹出时,而不是在列表几乎为空时,您的递归应该停止:
def removepair(no):
L = len(no)
if L <= 1:
return no
i = 1
while i < len(no):
if no[i] == no[i-1]:
no.pop(i)
no.pop(i-1)
i -= 1
i += 1
if len(no) < L:
# elements where popped since the list len has decreased
return removepair(no)
else:
return no
您的代码难以理解,因为它混合了递归和副作用。通常,您可以使用其中一个。在这里,您可以将您的递归调用替换为一段时间:
def removepair(no):
while True:
L = len(no)
if L <= 1:
return no
i = 1
while i < len(no):
if no[i] == no[i-1]:
no.pop(i)
no.pop(i-1)
i -= 1
i += 1
if len(no) == L: # no elements where popped
return no
但这不是真正的Pythonic,我认为您不应在函数内部修改参数no
,而应返回一个新列表。为什么不遍历该列表并且不复制结果中的重复项?
def removepair(no):
ret = []
for e in no:
if ret and e == ret[-1]: # current element is the same as the last element
ret.pop()
else:
ret.append(e)
return ret
或折叠:
def removepair(no):
import functools
return functools.reduce(lambda acc, x: acc[:-1] if acc and acc[-1]==x else acc+[x], no, [])