列表理解与可迭代。 Python新手

时间:2015-11-30 02:03:36

标签: python list-comprehension

说我有一个数组:

array=[1,0,2,3,4,0,0,5,6,0]

我想要一个只返回数字而不是零的列表。所以我做了这个并且它有效:

print(list(y for y in array if y!=0)

我尝试了另一种没有列表理解的方法,它不起作用,有人可以解释原因吗?

for y in array:
    if y!=0:
        print(list(y))

在没有0的情况下打印仅包含数字的列表的另一种方法是什么?

编辑:我试图使用for循环来解决这个问题,如果我在顶部创建一个空列表,它就可以工作。它有效,但我不明白为什么!但为什么这个工作而另一个不工作呢?什么更有效,这个或列表在速度/内存方面的理解?

array=[1,0,2,3,4,0,0,5,6,0]
list=[]
for y in array:
    if y!=0:
        list.append(y)
print(list)

5 个答案:

答案 0 :(得分:3)

让我们好好看看你认为正确的事情:

for y in array:
    if y!=0:
        print(list(y))

所以我们遍历数组中的每个值。如果值不为零,我们打印list(y)。问题从这里开始。由于y是整数,list(y)会返回错误,因为您无法将整数转换为列表。如果你做print(y),那就行了。

然后又出现了另一个问题。如果我们打印列表中不是零的每个元素,我们得到类似的东西,因为该代码只会按顺序打印:

1
2
3
4
5
6

您在问题中说明您想要列表。所以这段代码也行不通,因为没有存储列表。所以我们最终到达正确的答案:

array=[1,0,2,3,4,0,0,5,6,0]
list=[]
for y in array:
    if y!=0:
        list.append(y)
print(list)

此答案存储列表中不为零的每个y值,然后最终打印出列表。

编辑:

这就是列表理解的工作原理:

首先,我不禁发现你发了一个语法错误。 :P你忘记了一个结束的parantheses!这是正确的代码: print(list(y for y in array if y != 0))

其次,我需要声明那是 NOT A LIST COMPREHENSION 。那是一台发电机。差别很小。

列表理解会在现场生成列表。列表理解如下所示:[y for y in array if y != 0]

您在上面使用的生成器是存储表达式。它看起来像这样:y for y in array if y != 0

因此,您可以直接转到list(y for y in array if y != 0

,而不是使用[y for y in array if y != 0]

所以现在我将解释“列表理解”(生成器表达式)实际上是如何工作的。它首先循环遍历array的每个值。它检查值是否不为零。如果不是,则将y添加到输出列表中。所以基本上,生成器表达式与带有for循环的第二个工作代码相同,除了python为你创建输出列表,增加了一些便利。

答案 1 :(得分:1)

当你创建一个for循环时,该循环中的所有内容 - 一切 - 每次循环执行一次。所以这一行:

print(list(y)) 

...通过循环打印每次旅行的新list。而在第一个版本中:

print(list(y for y in array if y!=0)) 

...只打印了一件事:list()理解的结果。

编辑:如果你想在第二个版本中修复'int' object is not iterable错误,你可以这样做:

for y in array:
    if y!=0:
        print([y])

list函数需要一个可迭代对象作为输入。一个整数是不可迭代的,所以我们用括号括起来把它放在list里面,这基本上做同样的事情。使用上面的版本,您将看到每次循环时都会创建一个新的list

答案 2 :(得分:1)

第二次尝试时,您list(y)应该y。由于y是单个int而不是可迭代的,list(y)失败。这是输出:

>>> array=[1,0,2,3,4,0,0,5,6,0]
>>> print(list(y for y in array if y!=0))
[1, 2, 3, 4, 5, 6]
>>> for y in array:
    if y!=0:
        print(list(y))


Traceback (most recent call last):
  File "<pyshell#49>", line 3, in <module>
    print(list(y))
TypeError: 'int' object is not iterable
>>> for y in array:
    if y!=0:
        print(y)


1
2
3
4
5
6

另一种方法是使用filter,如下所示:

>>> print(list(filter(bool,array)))
[1, 2, 3, 4, 5, 6]

filter接受一个函数并且可迭代,将函数应用于iterable中的每个项目,并仅返回函数返回truthy值的函数。如果y为0(假),则bool为False,否则为True,它完全适用于这些目的。不过,看到你也可以这样做可能会有用:

>>> print(list(filter(lambda x:x != 0, array)))
[1, 2, 3, 4, 5, 6]

我看到你也在想为什么第一个版本有效。

>>> print(list(y for y in array if y!=0))

在这里,for y in array是一个生成器,这是一种特殊的Python对象,每当你提出一个值时就会吐出一个值,可以这么说。所以让我这样分解:

print(                              )    #Print
      list(                        )     #Convert iterable to list
             for y in array              #For each y in array...
                            if y!=0      #If y is not zero...
           y                             #Include y in the iterable for list()

这有帮助吗?

答案 3 :(得分:1)

如果您想使用for循环执行此操作,则需要执行以下操作:

nonzero = []
for y in array:
   if y != 0:
      nonzero.append(y)
print(nonzero)

但是在可读性和速度方面,列表理解或filter会更好。

答案 4 :(得分:0)

list()是一个构造函数,它接受零参数或可迭代的参数,例如list,str或tuple。问题是int不是可迭代的,其中作为列表推导([y y in in array if y!= 0])返回一个iterable并可用于创建列表Python documentation