Python-列表理解,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

我想知道如何从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]
    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
在您的列表理解中始终是一个空列表,即使您认为它在添加到它的过程中,这与第二个代码(double
for
循环)的情况不同

我要做的是使用
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
在您的列表理解中始终是一个空列表,即使您认为它在添加到它的过程中,这与第二个代码(double
for
循环)的情况不同

我要做的是使用
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
循环的
有什么原因吗?您可能应该提到列表理解/过滤器/