Python 更新函数参数中列表的范围
要解决的问题:定义一个Python函数remdup(l),该函数接受一个非空的整数列表l 并删除l中的所有重复项,只保留每个数字的最后一次出现。例如: 如果我们通过这个论点,那么remdup([3,1,3,5])应该会给我们一个结果[1,3,5]Python 更新函数参数中列表的范围,python,python-3.x,list,Python,Python 3.x,List,要解决的问题:定义一个Python函数remdup(l),该函数接受一个非空的整数列表l 并删除l中的所有重复项,只保留每个数字的最后一次出现。例如: 如果我们通过这个论点,那么remdup([3,1,3,5])应该会给我们一个结果[1,3,5] def remdup(l): for last in reversed(l): pos=l.index(last) for search in reversed(l[pos]): if s
def remdup(l):
for last in reversed(l):
pos=l.index(last)
for search in reversed(l[pos]):
if search==last:
l.remove(search)
print(l)
remdup([3,5,7,5,3,7,10])
# intended output [5, 3, 7, 10]
在循环的第4行中,我希望反向函数检查除索引[last]之外的每个数字,但如果我使用上面代码中的方法,它将取pos处的值,而不是索引号。如何解决这个问题?您需要反转整个切片,而不仅仅是一个元素:
for search in reversed(l[:pos]):
请注意,在迭代时修改列表可能会遇到问题。看
我花了几分钟才弄明白这个笨拙的逻辑。相反,您需要列表的其余部分:
for search in reversed(l[pos+1:]):
输出:
[5, 3, 7, 10]
您的原始算法可以改进。嵌套循环会导致一些不必要的复杂性 或者,您可以执行以下操作:
def remdup(l):
seen = set()
for i in reversed(l):
if i in seen:
l.remove(i)
else:
seen.add(i)
print(l)
我使用“seen”集合来跟踪已经出现的数字
但是,这将更有效率:
def remdup(l):
seen = set()
for i in range(len(l)-1, -1, -1):
if l[i] in seen:
del l[i]
else:
seen.add(l[i])
print(l)
在第二个算法中,我们使用一个范围以相反的顺序迭代列表,然后删除“seen”中已经存在的任何项。我不确定reversed()和remove()的实现是什么,所以我不能说对时间/空间复杂性的确切影响。但是,可以清楚地看到第二种算法中发生了什么,因此我认为这是一种更安全的选择。这是一种相当低效的实现方法:
def remdup(l):
i = 0
while i < len(l):
v = l[i]
scan = i + 1
while scan < len(l):
if l[scan] == v:
l.remove(v)
scan -= 1
i -= 1
scan += 1
i += 1
l = [3,5,7,5,3,7,10]
remdup(l)
print(l)
def remdup(l):
i=0
而我
它基本上遍历列表(按i
索引)。对于每个元素,它在列表中向前扫描匹配项,对于找到的每个匹配项,它删除原始元素。由于删除元素会移动索引,因此在继续之前会相应地调整其两个索引
它利用了内置的“从列表中删除第一个值等于x的项”。这里是另一个解决方案,向后迭代并弹出以前遇到的项的索引:
def remdup(l):
visited= []
for i in range(len(l)-1, -1, -1):
if l[i] in visited:
l.pop(i)
else:
visited.append(l[i])
print(l)
remdup([3,5,7,5,3,7,10])
#[5, 3, 7, 10]
使用字典:
def remdup(ar):
d = {}
for i, v in enumerate(ar):
d[v] = i
return [pair[0] for pair in sorted(d.items(), key=lambda x: x[1])]
if __name__ == "__main__":
test_case = [3, 1, 3, 5]
output = remdup(test_case)
expected_output = [1, 3, 5]
assert output == expected_output, f"Error in {test_case}"
test_case = [3, 5, 7, 5, 3, 7, 10]
output = remdup(test_case)
expected_output = [5, 3, 7, 10]
assert output == expected_output, f"Error in {test_case}"
解释
- 在字典中保留数字每次出现的最后一个索引。因此,我们的存储方式如下:
dict[number]=last\u occurrence
- 按值对字典排序,并使用列表理解从字典的键创建新列表
- 除了其他正确答案,这里还有一个
from iteration_utilities import unique_everseen,duplicates
import numpy as np
list1=[3,5,7,5,3,7,10]
dup=np.sort(list((duplicates(list1))))
list2=list1.copy()
for j,i in enumerate(list2):
try:
if dup[j]==i:
list1.remove(dup[j])
except:
break
print(list1)
这一行怎么样:(转换成函数对于练习来说很容易) 如果不需要新列表,可以改为:
lst[:] = list(dict.fromkeys(reversed(lst)))[::-1]
它不起作用,但它以任何方式使用最后一个元素,而且它更易于用我的代码实现。非常感谢。真的很感谢你这么说很高兴听到你这么说。但是,请查看迭代和删除的链接,并考虑转换逻辑。您所做的有点敏感,即使您正在为list.Hmmm使用临时值。可以我一定会抢的。耶!成功了。但是你能解释一下米德解释的答案吗。有几十种方法可以实现你的目标。这只是一个例子!哦。是的,还有其他的方法。我是初学者。
lst[:] = list(dict.fromkeys(reversed(lst)))[::-1]