博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python改了代码没有生效,关于python:为什么我在使用这段代码时没有更改列表?...
阅读量:6694 次
发布时间:2019-06-25

本文共 2833 字,大约阅读时间需要 9 分钟。

我希望使用此结构来延迟列表中的重复元素,但使用此代码时列表保持不变。有人能帮我吗?

例如,item=[1,2,3,4,5,6,7,8,9,1,2,6,7]

def duplicated(item):

i=0

j=0

while i

while j

if item[j]==item[i] and i!=j:

del item[j]

j+=1

i+=1

return item

没有重复。一些数字会被删除;在函数之后肯定不会改变。你在问它为什么不删除所有的重复项吗?

是的,对不起,我在问为什么它没有把所有的副本都延迟。

尝试运行它,例如pythontutor.com/visualize.html mode=edit-有些会被删除,但您的逻辑是错误的,所以并不是所有对都进行比较。

迭代时如何从列表中删除项的可能重复项?或者正如我(删除的)回答中所提到的:如何从列表中删除重复项同时保留

您在迭代列表时正在修改它。看看那个混蛋为什么不行。

@Patrickartner说,我不介意一个解释为什么OP的代码不起作用的答案。如果你链接到一个现有的问题而不是(重新)发布现有的解决方案,我更愿意。

循环中如何从python列表中删除项的可能重复项?

为了解决代码不工作的原因,这是因为您在函数开始时初始化了j,所以在i循环的第一次迭代之后,它是len(item)-1,然后再也不会为将来的循环重置。

这意味着你错过了许多副本。

所以,既然我们需要在每个循环中初始化它,我们仍然需要知道该怎么做。如果我们将其初始化为0,那么我们将检查列表中当前j值后面的重复项,这样做是浪费时间。为了提高效率,我们应该将其初始化为i+1,以便我们检查i后面的数字是否有重复项,因为我们已经知道列表中索引i之前i处的值没有重复项。这也简化了if,因为我们不再需要检查i != j。

最后一件事是,当使用del删除j时,后面的所有索引现在都向下移动了一个。因此,我们还需要从j中减去1,这样我们就可以直接检查刚刚删除的元素之后的元素,它现在与刚刚删除的元素索引相同(因为它们被下移)。

所以,在代码中:

def duplicated(item):

i = 0

while i < len(item):

j = i + 1

while j < len(item):

if item[j] == item[i]:

del item[j]

j -= 1

j += 1

i += 1

return item

它与人们给出的例子一起工作:

>>> duplicated([1,2,3,4,5,6,7,8,9,1,2,6,7])

[1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> duplicated([1,2,3,4,5,6,7,8,9,1,1,2,6,7])

[1, 2, 3, 4, 5, 6, 7, 8, 9]

但是,由于我们使用的是嵌套循环,所以所用的时间与输入列表的平方大小成正比,因此该解决方案是目前的O(n^2)复杂性解决方案。

但是,如果我们能够将算法修改为只使用一个循环,我们将把复杂性降低到O(n)。这可以通过使用查找集来完成。添加和检查集合中的元素是否是EDOCX1(平均大小写21),这样我们就可以使用它们来加快速度。

因此,如果我们有一个集合包含我们已经看到的元素,那么对于每个未来的元素,如果它已经在seen集合中,我们删除它,否则我们将它添加到这个集合中。

所以,在代码中:

def duplicated(item):

seen = set()

i = 0

while i < len(item):

if item[i] in seen:

del item[i]

else:

seen.add(item[i])

i += 1

return item

我可以确认这也通过了上面的测试用例。

我要指出的最后一点是,在这里删除元素时,我没有从指针中减去,这是因为在我们减去之前,我们知道它稍后会增加,我们希望它是相同的,但是在这里,它只在else块中增加,所以如果我们不做任何事情,它将保持不变。

这里可以找到其他解决方案。

实际上,变量j应该从i选择的下一项开始。

def duplicated(item):

i=0

while i

j = i+1

while j

if item[j]==item[i] and i!=j:

del item[j]

j -= 1

j+=1

i+=1

return item

每次嵌套while循环开始时需要重新初始化j:

def duplicated(item):

i=0

j=0

while i

j=i+1

while j

if item[j]==item[i]:

del item[j]

j -= 1

j+=1

i+=1

return item

。出

[1, 2, 3, 4, 5, 6, 7, 8, 9]

但是,您可以尝试以下更简单的代码,它将保持列表的插入顺序

def duplicated(item):

unique_list=[]

for i in item:

if i not in unique_list:

unique_list.append(i)

return unique_list

这会对输入[1,2,1,1]引发索引错误。另外,第二个解决方案是可怕的,因为它是O(n^2)。请链接到现有问题以获得解决方案,而不是发布自己的(坏)解决方案。

@阿兰·费伊,对新手来说应该很好,因为他们首先应该专注于工作,然后才能专注于效率。

@Aran Fey使用一个for循环,它将是O(n^2)

if i not in unique_list

@aran fey您所指的问题明确要求效率时间,但这个问题需要代码来工作,并且他使用的while循环代码比我建议的备用代码更复杂。

你应该在i循环的每一圈重新初始化你的jvar,否则,在第一次迭代之后,j总是等于len(item)。

def duplicated(item):

i=0

while i

j=0

while j

if item[j]==item[i] and i!=j:

print(i,j )

del item[j]

j+=1

i+=1

return item

但是,如果不关心列表顺序,最好的方法可能是将列表转换为一个集合,然后再转换回一个列表,有一个集合只能有不同的元素。

def duplicated(item):

return list(set(item))

警告:集合无序

您还可以使用i+1初始化j,并节省一些周期。

代码仍然有错误。它对输入[1,2,3,4,5,6,7,8,9,1,1,2,6,7]抛出一个索引错误。

list(OrderedDict([(i, None) for i in item]).keys())保留订单

转载地址:http://dxdoo.baihongyu.com/

你可能感兴趣的文章
《结对-结对编项目作业名称-需求分析》
查看>>
iView3.x Anchor(锚点)组件 导航锚点
查看>>
Network --- Tcp Protocol
查看>>
sqlite效率探测
查看>>
React生命周期
查看>>
数据库 -- mysql表操作
查看>>
shutil 高级文件操作
查看>>
Itellij Idea全局搜索
查看>>
Android系统简介
查看>>
配置证书
查看>>
Oracle VM VirtualBox技巧
查看>>
uvm_svcmd_dpi——DPI在UVM中的实现(二)
查看>>
Crimm Imageshop 2.3。
查看>>
SQL AND和OR求值顺序
查看>>
买房必知的五大法律常识 助你安心顺利选房
查看>>
leetcode563
查看>>
剑指Offer 40 最小的k个数
查看>>
winform创建树形菜单的无限级分类
查看>>
017——数组(十七) asort ksort rsort arsort krsort
查看>>
从此不再惧怕URI编码:JavaScript及C# URI编码详解
查看>>