从python中的列表列表中筛选出一个列表

从python中的列表列表中筛选出一个列表,python,list,Python,List,我是python新手,我正在尝试比较列表中的元素和列表中的元素 我有一个列表和一个列表,其中包含相同课程的不同组合(每个列表都是不同的拓扑排序) 在某些情况下,列表的列表是巨大的。 我想做的是将课程列表与课程列表列表进行比较,并将每个列表的非公共元素作为结果,例如: # the small list: courses_taken = ['CS350','CS450'] # a list of lists: list_of_lists =[['CS450', 'CS350', 'CS300',

我是python新手,我正在尝试比较列表中的元素和列表中的元素

我有一个列表和一个列表,其中包含相同课程的不同组合(每个列表都是不同的拓扑排序)

在某些情况下,列表的
列表是巨大的。
我想做的是将
课程
列表与
课程列表
列表进行比较,并将每个列表的非公共元素作为结果,例如:

# the small list:
courses_taken = ['CS350','CS450']

# a list of lists:
list_of_lists =[['CS450', 'CS350', 'CS300', 'CS206', 'CS306'], ['CS450', 'CS350', 'CS206', 'CS306', 'CS300'], ['CS450', 'CS350', 'CS206', 'CS300', 'CS306'],...]

# the result:
result = [['CS300', 'CS206', 'CS306'], ['CS206', 'CS306', 'CS300'], [ 'CS206', 'CS300', 'CS306']]

从我所做的研究中,我发现只有将课程与子列表进行比较的方法,而不是将每个具体元素进行比较,以返回非常见元素。此外,我还找到了比较两个列表的方法,但相同的代码不适用于这种情况

您可以使用
课程
创建一个
集合
,以便在
操作中更快地
——如果课程列表很长,这将很重要

然后只需在列表列表上迭代,并构建一个新列表来检查集合是否包含

>>> ctset = set(courses_taken)
>>> result = [[item for item in li if item not in ctset] for li in list_of_lists]
>>>
>>> # Or if it really matters, it can be a one-liner.
>>> result = [[item for item in li if item not in set(courses_taken)] for li in list_of_lists]
为了演示检查
列表
的组成员资格与检查
集合
之间的区别,我们可以设置两个timeit测试

>>> from random import randint
>>> import timeit
>>> 
>>> li = list(range(5000))
>>> se = set(li)
>>> 
>>> timeit.timeit("randint(0, 5000) in li", globals=globals(), number=10**6)
33.735417196992785
>>> timeit.timeit("randint(0, 5000) in se", globals=globals(), number=10**6)
1.196909729973413
>>> 
在这种情况下,set操作快了30倍以上

这说明了在两种不同数据类型上操作的时间复杂性起作用的情况。检查组成员资格的
set
是一个O(1)操作,其中列表是一个O(n)操作

此测试中的操作数量相当高,但可以与某些应用程序进行比较。我有一个组合数学问题的解决方案,涉及到大量的组成员检查,这非常缓慢,直到我将列表更改为集合。因此,这确实转化为现实世界中的应用程序性能


如果您对其他数据类型的操作感兴趣,可以查看此参考:

真正简单的列表理解是:

>>> result = [[x for x in group if x not in courses_taken] for group in list_of_lists]
>>> # output: [['CS300', 'CS206', 'CS306'], ['CS206', 'CS306', 'CS300'], ['CS206', 'CS300', 'CS306']]

这似乎是一个常见的问题。您是否尝试搜索此内容以查看是否已经有您可以使用的解决方案?@Todd实际上我确信我们可以找到答案,但我已经搜索了,在这种情况下,提供答案更容易(正如您所做的那样),稍后将被其他参与者关闭。@Todd说实话,即使我搜索了,也找不到答案。我只找到了打印常用列表的方法,或者将整个列表作为一个列表与每个子列表进行比较,而不是与元素进行比较。也许有些东西我没找到。如果是这样的话,那就是我的错误。总之,谢谢你们两位的帮助!不客气。欢迎这么说。这实际上只在一行中运行得很好,而不需要创建一组列表。非常感谢你!从列表中创建一个集合@piggy的原因是
中对列表的
操作非常慢。在
中使用列表与在循环中使用集合的区别非常明显。它可以将一分钟的操作变成几秒钟的操作。我提到,如果名单更长,那么在我的回答中就很重要了。你可以选择你喜欢的答案,但从技术上讲,我的建议更好。我的错误是,当时我不知道这一点,也许在你写答案时我没有注意到这一点。既然是这样,从长远来看,你的回答可能会对我有更大的帮助,因为这个列表在某个时候会变得更大。再次感谢你@Todd!它工作得很好,但在Missilexent的回答中,它只在一行代码中工作,因此我选择了那一行。但是这个也能用!我希望你明白你的标准并不那么合理;-)感谢您对本主题的进一步解释!