python删除列表中全部元素_关于python:删除一个列表中出现的所有元素

假设我有两个列表,l1和l2。我想执行l1 - l2,它返回l1的所有元素,而不是l2中的元素。

我可以想到一个简单的循环方法来实现这一点,但这将是非常低效的。做这件事的方法是什么?

例如,如果我有l1 = [1,2,6,8] and l2 = [2,3,5,8],l1 - l2应该返回[1,6]。

只是一个提示:pep8声明不应该使用小写"l",因为它看起来太像1。

Python有一个称为列表理解的语言特性,非常适合让这类事情变得非常简单。以下语句完全满足您的需要,并将结果存储在l3中:

l3 = [x for x in l1 if x not in l2]

l3将包含[1, 6]。

希望这有帮助!

很像Python,我喜欢!它的效率如何?

我相信这是非常有效的,而且它的好处是非常易读和清楚地知道你想要完成什么。我看到一篇关于效率的博客文章,你可能会发现它很有趣:blog.cdleary.com/2010/04/efficiency-of-list-understructions

@fandom:列表理解本身是非常有效的(虽然生成器理解可能通过不在内存中复制元素而更有效),但是in操作符在列表上没有那么有效。列表中的in是o(n),而集合中的in是o(1)。然而,在你得到成千上万个元素或者更多之前,你不太可能注意到它们之间的区别。

l3 = [x for x in l1 if x not in set(l2)]?我敢肯定,是否会不止一次地打电话给埃多克斯。

@丹诺苏尔:是的,对于l1的每个元素都会调用set(l2)。一般来说,如果你要经常使用in,你可能不应该首先使用一个列表(或tuple)(尽管如果你知道它总是很小的话,那就不可怕了)。

对于需要集合的O(1)数而不想一次又一次调用set的大列表,可以使用[x for l2s in [set(l2)] for x in l1 if x not in l2s]。

你也可以设置l2s = set(l2),然后说l3 = [x for x in l1 if x not in l2s]。稍微容易一点。

如果你能使用set,你应该使用arkku的答案。它既高效又可读。我无法在应用程序中使用集合,因为我的项目不可哈希。

仅供参考,在l3 = [x for x in l1 if x not in set(l2)]中…set(l2)部分只运行一次,因此这应该是最有效、可读的答案,不会删除重复项或重新排序列表。

@EricLindauer:如果用print(x)替换x not in set(l2)的话,就会看到l1的每个元素都被打印到stdout,即每次迭代都会调用print函数。同样适用于set(l2)。

谢谢,功能很好

谢谢,我半个小时来一直在自己想同样的问题,但你的答案却成功了!

我不同意我建议的编辑的拒绝原因:stackoverflow.com/review/suggested-edits/20710254我的编辑确实使答案更容易阅读,而且我的编辑编辑出来的内容是多余的。当先前的编辑尝试被拒绝时,我也提出了同样的批评,我的评论也被删除了。天哪!如果你必须拒绝编辑,评论家,但让我的批评站在一边。

我的首选答案。

一种方法是使用集合:

>>> set([1,2,6,8]) - set([2,3,5,8])

set([1, 6])

这也将从l1中删除重复项,这可能是不希望的副作用。

…并失去元素顺序(如果顺序很重要)。

对不起,帮派,这是最好的答案,也是最简单的读物。我需要生成随机密钥,并将其存储在列表中。我要确保它们是独一无二的。所以我有一个从1到10000的范围,然后我有一个我生成的数字列表。一个很好的解决方案如下:random.sample(set(range(1,10))-set([2,3]),1)

@如果你的物品是可以散列的,那么Tereuscott是最好的答案。在我的例子中,它们不是,所以我必须使用选定的答案。

需要注意的是,集合的输出是有序的,即1,3,2变为1,2,3和A、C、B变为A、B、C并且您可能不想这样做。

扩展到油炸圈饼的答案和其他答案,通过使用生成器理解而不是列表理解,以及使用set数据结构(因为in运算符在列表上是O(n),而在集合上是O(1),可以获得更好的结果。

这里有一个对你有用的函数:

def filter_list(full_list, excludes):

s = set(excludes)

return (x for x in full_list if x not in s)

结果将是一个iterable,它将懒惰地获取筛选列表。如果您需要一个真正的列表对象(例如,如果您需要对结果执行EDOCX1[5]),那么您可以轻松地构建这样的列表:

filtered_list = list(filter_list(full_list, excludes))

使用python集类型。那将是最严重的Python。:)

而且,由于它是本地的,所以它也应该是最优化的方法。

见:

http://docs.python.org/library/stdtypes.html设置

http://docs.python.org/library/sets.htm(对于旧版python)

# Using Python 2.7 set literal format.

# Otherwise, use: l1 = set([1,2,6,8])

#

l1 = {1,2,6,8}

l2 = {2,3,5,8}

l3 = l1 - l2

在使用集合时,应注意的是,的输出是有序的,即1,3,2变为1,2,3和A、C、B变为A、B、C,您可能不想这样做。

如果列表l1包含重复元素,此方法将不起作用。

作为一种替代方法,您也可以将filter与lambda表达式一起使用,以获得所需的结果。例如:

>>> l1 = [1,2,6,8]

>>> l2 = set([2,3,5,8])

#     v  `filter` returns the a iterator object. Here I'm type-casting

#     v  it to `list` in order to display the resultant value

>>> list(filter(lambda x: x not in l2, l1))

[1, 6]

性能比较

这里我比较一下这里提到的所有答案的性能。正如预期的那样,Arkku基于set的运营速度最快。

Arkku的设置差异-第一个(每个循环0.124 usec)

mquadri$ python -m timeit -s"l1 = set([1,2,6,8]); l2 = set([2,3,5,8]);""l1 - l2"

10000000 loops, best of 3: 0.124 usec per loop

Daniel Pryden对set查找的列表理解-秒(每个循环0.302 usec)

mquadri$ python -m timeit -s"l1 = [1,2,6,8]; l2 = set([2,3,5,8]);""[x for x in l1 if x not in l2]"

1000000 loops, best of 3: 0.302 usec per loop

甜甜圈的清单理解在普通清单-第三个(0.552个使用循环)

mquadri$ python -m timeit -s"l1 = [1,2,6,8]; l2 = [2,3,5,8];""[x for x in l1 if x not in l2]"

1000000 loops, best of 3: 0.552 usec per loop

Moinuddin Quadri使用filter四分之一(每个循环0.972 usec)

mquadri$ python -m timeit -s"l1 = [1,2,6,8]; l2 = set([2,3,5,8]);""filter(lambda x: x not in l2, l1)"

1000000 loops, best of 3: 0.972 usec per loop

Akshay Hazari使用reduce+filter-第五个(每个回路3.97 usec)

mquadri$ python -m timeit"l1 = [1,2,6,8]; l2 = [2,3,5,8];""reduce(lambda x,y : filter(lambda z: z!=y,x) ,l1,l2)"

100000 loops, best of 3: 3.97 usec per loop

ps:set不维护顺序,从列表中删除重复元素。因此,如果您需要其中任何一个,请不要使用设置差异。

尽管reduce和map在计算出您想要的输出时更加灵活。其他一切都比它强,真是糟透了。

替代解决方案:

reduce(lambda x,y : filter(lambda z: z!=y,x) ,[2,3,5,8],[1,2,6,8])

使用这种方法有什么好处吗?它看起来更复杂,更难阅读,没有太多好处。

这似乎很复杂。reduce非常灵活,可以用于很多目的。它被称为褶皱。还原实际上是折叠的。假设您想在函数中添加更复杂的内容,那么在这个函数中是可能的,但是列表理解(选择的最佳答案)只会获得相同类型的输出,即列表,可能具有相同的长度,而使用折叠,您也可以更改输出类型。en.wikipedia.org/wiki/fold_28高阶_函数%29。此解决方案的复杂性为n*m或更低。不过,其他人可能会更好,也可能不会更好。

减少(功能、列表、初始累加器(可以是任何类型)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Python的while和for是两种常见的循环结构。 while循环用于在满足条件的情况下重复执行一段代码,直到条件不再满足为止。while循环的语法如下: ``` while 条件: 循环体 ``` 例如,以下代码将打印出1到10的数字: ``` i = 1 while i <= 10: print(i) i += 1 ``` for循环用于遍历一个序列(如列表、元组、字符串等)的每个元素,并对每个元素执行一些操作。for循环的语法如下: ``` for 变量 in 序列: 循环体 ``` 例如,以下代码将打印出列表的每个元素: ``` fruits = ['apple', 'banana', 'orange'] for fruit in fruits: print(fruit) ``` 总的来说,while循环适用于需要重复执行某个操作,但不知道具体执行次数的情况;而for循环适用于遍历序列元素,对每个元素执行相同的操作。 ### 回答2: 在Python,while循环和for循环都是用来执行重复的代码块。 while循环的语法结构是:while 循环条件: 重复执行的代码 它会在每次循环开始前先判断循环条件是否为真,只有当循环条件为真时,循环才会继续执行。当循环条件为假时,循环结束。 例如,我们可以使用while循环来计算1到10的和: sum = 0 i = 1 while i <= 10: sum += i i += 1 print(sum) # 输出55 for循环的语法结构是:for 变量 in 可迭代对象: 重复执行的代码 它可以用来遍历一个可迭代对象的每个元素,并执行相应的代码。可迭代对象可以是列表、元组、字符串等。 例如,我们可以使用for循环来遍历一个列表并输出每个元素: fruits = ["apple", "banana", "cherry"] for fruit in fruits: print(fruit) for循环还可以与range()函数配合使用,用来执行指定次数的循环。 例如,我们可以使用for循环来打印数字1到5: for i in range(1, 6): print(i) 在实际应用,while循环适用于没有确定的迭代次数的情况,而for循环适用于已知迭代次数的情况。根据具体的需求,选择使用while循环或for循环可以使代码更加简洁、高效。 ### 回答3: 在Python,while循环和for循环是两种常用的迭代结构,可以有效地完成各种重复的任务。 首先是while循环。它会根据所给定的条件是否满足,来反复执行一组语句。例如,我们可以使用while循环计算某个数的阶乘: ```python n = 5 factorial = 1 while n > 0: factorial *= n n -= 1 print("5的阶乘是:", factorial) ``` 在上述例子,我们使用while循环不断将n的值递减,同时用factorial累积乘积。当n变为0时,循环结束,打印出结果。 接下来是for循环。它可以遍历一个可迭代对象元素,并为每个元素执行一组语句。例如,我们可以使用for循环打印出列表的每个元素: ```python fruits = ["apple", "banana", "orange"] for fruit in fruits: print(fruit) ``` 上述代码,我们使用for循环遍历了一个名为fruits的列表,将每个元素依次赋值给变量fruit,并打印出来。 除了遍历列表外,for循环还可以遍历字符串、元组、字典等其他可迭代对象。甚至可以和range()函数结合使用,进行定长的循环: ```python for i in range(5): print(i) ``` 上述代码,我们使用for循环结合range()函数打印出了0到4的整数。 总结起来,Python的while循环和for循环是两种常用的迭代结构,while循环适用于不清楚循环次数的情况,而for循环适用于遍历可迭代对象的情况。根据具体的需求,选择合适的循环结构可以简化代码,提高效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值