Python:list()函数会弄乱映射()

Python:list()函数会弄乱映射(),python,python-3.x,list,dictionary,filter,Python,Python 3.x,List,Dictionary,Filter,我在Python3上玩了一些map()和filter()函数。 我尝试获取一个列表并对其进行过滤,然后在filter对象上执行映射功能: f = list(range(10)) print(f) print('-----------') y = filter(lambda a: a > 5, f) print(list(y)) print(y) print(type(y)) print('-----------') x = map(lambda value: value+1, y) pri

我在Python3上玩了一些
map()
filter()
函数。 我尝试获取一个列表并对其进行过滤,然后在filter对象上执行映射功能:

f = list(range(10))
print(f)
print('-----------')
y = filter(lambda a: a > 5, f)
print(list(y))
print(y)
print(type(y))
print('-----------')
x = map(lambda value: value+1, y)
print(list(y))
print(y)
print(type(y))
print('-----------')
print(list(x))
print(x)
print(type(x))
结果是:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
-----------
[6, 7, 8, 9]
<filter object at 0x7f46db255ac8>
<class 'filter'>
-----------
[]
<filter object at 0x7f46db255ac8>
<class 'filter'>
-----------
[]
<map object at 0x7f46db3fc128>
<class 'map'>
[0,1,2,3,4,5,6,7,8,9]
-----------
[6, 7, 8, 9]
-----------
[]
-----------
[]
当我注释掉
打印(列表(y))
时,它突然运行良好。 你遇到过这个吗?我做错了什么?
我在ubuntu上运行python 3.6.3。

迭代器和生成器只能使用一次。当您调用
list(y)
时,它会生成序列中的所有值,然后被耗尽。当您第二次尝试查看内容时,没有什么可供参考的,因此您会得到一个空列表

这在以下方面得到了更清楚的证明:

f = list(range(10))
print(f)
print('-----------')
y = filter(lambda a: a > 5, f)
print(list(y))
print(list(y))
其中:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
-----------
[6, 7, 8, 9]
[] # Nothing to yield
如果要将值保留在
y
中,则需要将其指定给一个名称:

y = list(filter(lambda a: a > 5, f))

我同意roganjosh的回答,但让我们看看我是否可以补充一点:

filter()
map()
reversed()
函数有点让人困惑,因为它们不返回列表(正如您所期望的那样),而是返回迭代器。(这在帮助文本中有说明,您可以在键入
help(filter)
help(map)
help(reversed)
时阅读这些文本)

既然您知道它们返回的是迭代器而不是列表,您可能会想:这有什么关系?好的,迭代器应该迭代一次(也就是说,不超过一次),就像在for循环中一样,比如迭代器中的i
for:
。需要记住的一点是,一旦迭代器被迭代,它就不再有更多的元素可以迭代了

说明,请考虑此代码:

backwards = reversed( [1, 2, 3, 4, 5] )   # creates an iterator; not a list!
myList = list(backwards)   # iterates over the iterator to create a list
print(myList)   # prints "[5, 4, 3, 2, 1]", as you'd expect
myList = list(backwards)   # nothing left to iterate over, so creates an empty list
print(myList)   # prints "[]" (an empty list)
那么,如果您想从
filter()
map()
reversed()
中获取列表,而不是从迭代器中获取列表,该怎么办?您可以立即将这些函数调用包装到
list()
中,并在需要时使用该结果,如下所示:

myList = list( reversed( [1, 2, 3, 4, 5] ) )
# Now use myList whenever you need it, without worrying that it will disappear.
f = list(range(10))
y = [a for a in f if a > 5]  # you can use this instead of filter()
x = [a + 1 for a in f]  # you can use this instead of map()
或者,您可以用列表理解替换
filter()
map()
,如下所示:

myList = list( reversed( [1, 2, 3, 4, 5] ) )
# Now use myList whenever you need it, without worrying that it will disappear.
f = list(range(10))
y = [a for a in f if a > 5]  # you can use this instead of filter()
x = [a + 1 for a in f]  # you can use this instead of map()
至于更换
反向()
?试试这个:

z = f[::-1]  # you can use this instead of reversed()
您可能想知道:如果我可以使用
filter()
map()
reversed()
的替换项,我为什么要使用它们呢


答案是,有时您需要过滤、映射或反转一个巨大的列表,而创建另一个(巨大的)列表只是为了循环/迭代将非常浪费时间。因此,返回一个迭代器可以防止另一个巨大的内存块被耗尽——只需知道,当迭代器用完(即迭代)时,它的信息就消失了。

y
上调用
list()
会消耗迭代器。迭代器只能使用一次。在
print()
中第二次调用
y
的输出时,没有剩余的值可供生成。您可以简单地通过:
y=filter(lambda:a>5,f)看到这一点;打印(列表(y));print(list(y))
@roganjosh您应该将此作为答案发布。正如@roganjosh所说,您可能需要将
list(filter…
存储到一个变量中,并在任何需要的地方使用它。@Austin很抱歉,我更正了它。@roganjosh谢谢!!如果我们想在将来使用
y
的话,我们不必每次都使用
list
我们称之为
y
@vash\u踩踏是的,这就是我在底线中的建议。调用
list()
第二次是第二次打印空list@vash_the_stampede我添加了一些说明,thanksyeah agree只是建议演示
y=list(filter(lambda a:a>5,f)
,以便在回答中让OP知道如何正确创建包含过滤列表的变量,“将筛选列表分配给变量的正确方法是…”,他现在知道如何不这样做,但还没有人演示如何正确创建变量
y