Python-列表理解,2D列表
我想知道如何从2D列表中删除重复项。比如说:Python-列表理解,2D列表,python,list-comprehension,Python,List Comprehension,我想知道如何从2D列表中删除重复项。比如说: x= [[1,2], [3,2]] 我想要结果: [1, 2, 3] 按这个顺序 实际上,我不明白为什么我的代码没有做到这一点: def removeDuplicates(listNumbers): finalList=[] finalList=[number for numbers in listNumbers for number in numbers if number not in finalList] retur
x= [[1,2], [3,2]]
我想要结果:
[1, 2, 3]
按这个顺序
实际上,我不明白为什么我的代码没有做到这一点:
def removeDuplicates(listNumbers):
finalList=[]
finalList=[number for numbers in listNumbers for number in numbers if number not in finalList]
return finalList
如果我用嵌套for循环的形式写它,它看起来是一样的
def removeDuplicates(listNumbers):
finalList=[]
for numbers in listNumbers:
for number in numbers:
if number not in finalList:
finalList.append(number)
return finalList
“问题”是这段代码运行得很好。第二个问题是秩序很重要。谢谢您首先将
finalList
声明为空列表,所以
if number not in finalList
将始终为False
作业开始前,将对你理解的右侧进行评估
在迭代器链上迭代。from_iterable
以通常的方式提供并删除重复项:
>>> from itertools import chain
>>> x=[[1,2],[3,2]]
>>>
>>> seen = set()
>>> result = []
>>> for item in chain.from_iterable(x):
... if item not in seen:
... result.append(item)
... seen.add(item)
...
>>> result
[1, 2, 3]
进一步阅读:
编辑:
您不需要导入来展平列表,只需使用生成器即可
(item for sublist in x for item in sublist)
而不是
chain。从_iterable(x)
首先声明finalList
为空列表,因此
if number not in finalList
将始终为False
作业开始前,将对你理解的右侧进行评估
在迭代器链上迭代。from_iterable
以通常的方式提供并删除重复项:
>>> from itertools import chain
>>> x=[[1,2],[3,2]]
>>>
>>> seen = set()
>>> result = []
>>> for item in chain.from_iterable(x):
... if item not in seen:
... result.append(item)
... seen.add(item)
...
>>> result
[1, 2, 3]
进一步阅读:
编辑:
您不需要导入来展平列表,只需使用生成器即可
(item for sublist in x for item in sublist)
而不是
chain。从_iterable(x)
首先计算右侧的表达式,然后将此列表理解的结果分配给finalList。
而在第二种方法中,在迭代之间,您一直在写这个列表。这就是区别
这可能与手册在编写for循环中的迭代iterable时警告意外行为的原因类似
您可以使用内置的
set()
-方法来删除重复项(之前必须在列表上执行flant()
)在将此列表理解的结果分配给最终列表之前,首先对右侧的表达式求值。
而在第二种方法中,在迭代之间,您一直在写这个列表。这就是区别
这可能与手册在编写for循环中的迭代iterable时警告意外行为的原因类似
您可以使用内置的
set()
-方法删除重复项(之前必须在列表上执行flant()
)在Python中无法引用当前压缩。事实上,如果删除不起任何作用的行finalList=[]
,您将得到一个错误
您可以通过两个步骤完成此操作:
finalList = [number for numbers in listNumbers for number in numbers]
finalList = list(set(finalList))
或者,如果您想要一行:
finalList = list(set(number for numbers in listNumbers for number in numbers))
Python中没有办法引用当前压缩。事实上,如果删除不起任何作用的行
finalList=[]
,您将得到一个错误
您可以通过两个步骤完成此操作:
finalList = [number for numbers in listNumbers for number in numbers]
finalList = list(set(finalList))
或者,如果您想要一行:
finalList = list(set(number for numbers in listNumbers for number in numbers))
finalList
在您的列表理解中始终是一个空列表,即使您认为它在添加到它的过程中,这与第二个代码(doublefor
循环)的情况不同
我要做的是使用set
:
>>> set(i for sub_l in x for i in sub_l)
{1, 2, 3}
编辑:
另一方面,如果订单很重要,并且接近您的尝试:
>>> final_list = []
>>> x_flat = [i for sub_l in x for i in sub_l]
>>> list(filter(lambda x: f.append(x) if x not in final_list else None, x_flat))
[] #useless list thrown away and consumesn memory
>>> f
[1, 2, 3]
或
EDIT2:
正如所提到的,映射
&过滤器
显然会丢弃最终无用的列表,更糟糕的是,它们会消耗内存。因此,我会像您在上一个代码示例中那样使用嵌套for
循环,但如果您希望使用列表理解方法,则:
>>> x_flat = [i for sub_l in x for i in sub_l]
>>> final_list = []
>>> for number in x_flat:
if number not in final_list:
finalList.append(number)
finalList
在您的列表理解中始终是一个空列表,即使您认为它在添加到它的过程中,这与第二个代码(doublefor
循环)的情况不同
我要做的是使用set
:
>>> set(i for sub_l in x for i in sub_l)
{1, 2, 3}
编辑:
另一方面,如果订单很重要,并且接近您的尝试:
>>> final_list = []
>>> x_flat = [i for sub_l in x for i in sub_l]
>>> list(filter(lambda x: f.append(x) if x not in final_list else None, x_flat))
[] #useless list thrown away and consumesn memory
>>> f
[1, 2, 3]
或
EDIT2:
正如所提到的,映射
&过滤器
显然会丢弃最终无用的列表,更糟糕的是,它们会消耗内存。因此,我会像您在上一个代码示例中那样使用嵌套for
循环,但如果您希望使用列表理解方法,则:
>>> x_flat = [i for sub_l in x for i in sub_l]
>>> final_list = []
>>> for number in x_flat:
if number not in final_list:
finalList.append(number)
谢谢你,但是我不能导入任何东西谢谢你,但是我不能导入任何东西为什么不首先展平
x
,因为你放弃了2D结构?为什么不首先展平x
,因为你放弃了2D结构?@timgeb…正确…我在OP中没有看到这一点requirement@H.Hasin .. 您不想使用嵌套for循环的有什么原因吗?您可能应该提到,列表理解/过滤器/映射有副作用和/或通过创建无用的一次性列表来消耗内存,这可能会让您大吃一惊。:>@铁拳最简单的解决方案是先扁平化,然后过滤,而不是坚持一行。您的第二次编辑与我的类似,但您的具有二次运行时。基本上有三种O(n)解决方案可以消除重复项,同时保持反复查看的顺序。第一个是我贴的。第二个是我的答案中链接中接受答案的列表理解,它有副作用,在生产代码中可能不是一件好事。第三个建议是滥用OrderedDict作为有序集(即,OrderedDict.fromkeys(iterable).keys()
)。另一个建议是:您可以将x_展开
作为生成器理解,而不是列表理解,以节省内存。@timgeb…正确…我在OP中没有看到这一点requirement@H.Hasin .. 您不想使用嵌套for
循环的有什么原因吗?您可能应该提到列表理解/过滤器/