python - 我想创建一个函数,它接受一个列表并返回相同的列表但没有重复的元素,这个程序有什么问题?
问题描述
我想做一个函数,它接受一个列表并返回相同的列表但没有重复的元素
def func(list1):
for i in range(len(list1)):
list2 = [x for x in list1 if x != list1[i]]
if list1[i] in list2:
list1.remove(i)
return list1
mylist = [1,2,3,4]
func(mylist)
解决方案
已经有很多答案展示了如何正确实现此任务,但没有一个讨论您的实际代码。
解构你的代码
希望这将有助于理解为什么您的代码不起作用。这是您的代码,添加了注释:
def func(list1):
for i in range(len(list1)):
list2 = [x for x in list1 if x != list1[i]]
在这里,您构造了一个list2
不包含的列表list1[i]
。
if list1[i] in list2:
这个if
陈述总是错误的,由list2
.
list1.remove(i)
即使您修复了if
语句的逻辑,list1.remove(i)
也会造成麻烦:尝试在迭代列表时删除列表的元素会使其余迭代的索引无效。最好避免这样做,而是将结果构建到一个新列表中。
此外,它正在list1.remove(i)
寻找价值并将其删除,无论它首先找到它。正如这段代码所期望的那样,它没有删除第 i 个元素。i
list1
return list1
而这个返回语句可能并不意味着缩进这么深,它应该可能for
与顶部的语句处于同一水平。
工作代码更接近你的逻辑
虽然我认为这不是最好的解决方案——其他答案提供了更好的解决方案——但这是一个受您的代码启发的解决方案,它有效。
def func(list1):
list2 = [] # We'll append elements here
for item in list1: # more pythonic way to loop over a list
if item not in list2:
list2.append(item)
return list2
我的首选解决方案
好的,所以现在我在其他答案中复制信息,但是使用 Python 3.7(*) 或更新版本,dict
保证插入其中的元素的顺序保持不变,我会使用@Pedro Maia 的解决方案:
def func(list1):
return list(dict.fromkeys(list1))
事实上,我最近在我的代码库中使用了这种技术。
在旧版本的 Python 中,dicts 没有排序。但是,自 Python 2.7 以来OrderedDict
,该库中一直存在该类collections
,因此此代码适用于任何版本的 Python >= 2.7:
from collections import OrderedDict
def func(list1):
return list(OrderedDict.fromkeys(list1))
如果您不熟悉它们,请查看collections
library和itertools
library,它们为各种问题提供了非常有用的帮助。
(*) 根据手册collections.OrderedDict
,Pythondict
只保证从 Python 3.7 开始订购,即使它们实际上是在 Python 3.6 中开始订购的,至少对于 CPython 实现是这样。另请参阅: 字典是否在 Python 3.6+ 中排序?
推荐阅读
- java - 如何检测哪个片段处于活动状态?
- fody - 仅选择自动实现属性的选项?
- eclipse-scout - SAAS 应用程序,每个公司的子域
- android - Android-Socket 不发送自定义对象
- arrays - React native 在数组中给对象一个名称
- python - python队列是否使用GIL?
- html - 如何将两个固定块之一的子元素(具有较低的 z-index)放在最顶部?
- c++ - boost::filesystem::path 只给出第一个字符
- docker - 绑定挂载和卷:文件最终不会在容器中?
- c# - 如何像我们在 php 中一样在 C# 中将变量放入图像源中