Python3.x 中的映射迭代器对象是否只能使用一次,为什么? (附上代码和例子)
Is a map iterator object in Python3.x can only be used once and why? (codes and examples attached)
使用此代码:
strs = ["111", "1000", "1000", "1000"]
# count the numbers of '0' and '1' respectively for each string in strs
counts = map(lambda x: [x.count('0'), x.count('1')], strs)
cntSortBy0 = sorted(counts, key=lambda x: x[0]) # sort with counts of '0'
cntSortBy1 = sorted(counts, key=lambda x: x[1]) # sort with counts of '1'
这里我有一个列表 strs
以字符串作为元素。
然后我分别计算 strs 中每个字符串的 '0' 和 '1' 的数量,并将结果保存在 counts
中(我在 python3 中使用 map 做到了这一点,所以 count
是一个地图对象)。
之后我第一次对 counts
进行排序,它工作正常,
但是当我第二次对 counts
进行排序时,它 returns 是一个空列表(cntSortBy1
是空的),
我发现这是因为counts
在第一次排序后变空了:
>>> strs = ["111", "1000", "1000", "1000"]
>>> counts = map(lambda x: [x.count('0'), x.count('1')], strs)
>>> cntSortBy0 = sorted(counts, key=lambda x: x[0]) # sort with counts of '0'
>>> list(counts)
[]
难怪cntSortBy1
是空的,但为什么会这样呢?
另外,如果我只是打印list(counts)
,cntSortBy1
也会变成空的,如下图,
>>> strs = ["111", "1000", "1000", "1000"]
>>> counts = map(lambda x: [x.count('0'), x.count('1')], strs)
>>> list(counts)
[[0, 3], [3, 1], [3, 1], [3, 1]]
>>> cntSortBy0 = sorted(counts, key=lambda x: x[0])
>>> cntSortBy0
[]
这是否意味着一个地图对象只能被使用一次,之后它就会变成一个空列表?
Py3中有没有其他具有相同特性的对象? (我试过range()
,不行。)
非常感谢!!!
在Python3map
returns一个迭代器中:
https://docs.python.org/3/library/functions.html#map
并且迭代器可以(并且应该)只使用一次。请参阅有关迭代器的官方文档:
https://docs.python.org/3/tutorial/classes.html#iterators
在您的情况下,您需要在创建时将 map
转换为 list
,这将解决您的问题:
counts = list(map(lambda x: [x.count('0'), x.count('1')], strs))
一旦迭代器用完(意味着完全迭代),就没有任何东西可以迭代了,所以第二次迭代不会产生任何结果。举个例子。
a = map(int,['1','2','3'])
for i in a:
print(i)
for i in a:
print(i)
这将输出:
1
2
3
每当你需要多次迭代一个迭代器时,把它变成一个列表(或其他类型的序列):
a = list(map(int,['1','2','3']))
这输出:
1
2
3
1
2
3
当使用 sorted()
时,您也在迭代 map
迭代器对象:
a = map(int,['1','2','3'])
print(sorted(a)) # output: [1, 2, 3]
print(sorted(a)) # output: []
a = list(map(int,['1','2','3']))
print(sorted(a)) # output: [1, 2, 3]
print(sorted(a)) # output: [1, 2, 3]
根据文档:https://docs.python.org/3/library/functions.html#map
map(function, iterable, ...)
Return an iterator that applies function to every item of iterable, yielding the results.
map 的作用是 returns 一个迭代器,您可以对其进行迭代,但是一旦完成对它的迭代,它就会变空,或者当您继续对其进行迭代时,迭代器的大小会不断减小
因此,当您通过 sorted(counts, key=lambda x: x[0])
对 map(lambda x: [x.count('0'), x.count('1')], strs)
返回的迭代器 counts
进行迭代时,它变为空
为避免这种情况,您需要使用 list(map(...))
将任何要重复使用的迭代器转换为列表,然后您可以随意使用它,例如。
In [1]: strs = ["111", "1000", "1000", "1000"]
In [2]: counts = list(map(lambda x: [x.count('0'), x.count('1')], strs))
In [3]: counts)
Out[3]: [[0, 3], [3, 1], [3, 1], [3, 1]]
In [4]: cntSortBy0 = sorted(counts, key=lambda x: x[0])
In [5]: cntSortBy0
Out[5]: [[0, 3], [3, 1], [3, 1], [3, 1]]
In [6]: counts
Out[6]: [[0, 3], [3, 1], [3, 1], [3, 1]]
In [7]: cntSortBy1 = sorted(counts, key=lambda x: x[1])
In [9]: cntSortBy1
Out[9]: [[3, 1], [3, 1], [3, 1], [0, 3]]
In [10]: counts
Out[10]: [[0, 3], [3, 1], [3, 1], [3, 1]]
如您所见,我们使用了两次counts
,但它从来没有为空,因为我们现在将其转换为一个列表,即使您迭代了无数次,它仍然完好无损。
使用此代码:
strs = ["111", "1000", "1000", "1000"]
# count the numbers of '0' and '1' respectively for each string in strs
counts = map(lambda x: [x.count('0'), x.count('1')], strs)
cntSortBy0 = sorted(counts, key=lambda x: x[0]) # sort with counts of '0'
cntSortBy1 = sorted(counts, key=lambda x: x[1]) # sort with counts of '1'
这里我有一个列表 strs
以字符串作为元素。
然后我分别计算 strs 中每个字符串的 '0' 和 '1' 的数量,并将结果保存在 counts
中(我在 python3 中使用 map 做到了这一点,所以 count
是一个地图对象)。
之后我第一次对 counts
进行排序,它工作正常,
但是当我第二次对 counts
进行排序时,它 returns 是一个空列表(cntSortBy1
是空的),
我发现这是因为counts
在第一次排序后变空了:
>>> strs = ["111", "1000", "1000", "1000"]
>>> counts = map(lambda x: [x.count('0'), x.count('1')], strs)
>>> cntSortBy0 = sorted(counts, key=lambda x: x[0]) # sort with counts of '0'
>>> list(counts)
[]
难怪cntSortBy1
是空的,但为什么会这样呢?
另外,如果我只是打印list(counts)
,cntSortBy1
也会变成空的,如下图,
>>> strs = ["111", "1000", "1000", "1000"]
>>> counts = map(lambda x: [x.count('0'), x.count('1')], strs)
>>> list(counts)
[[0, 3], [3, 1], [3, 1], [3, 1]]
>>> cntSortBy0 = sorted(counts, key=lambda x: x[0])
>>> cntSortBy0
[]
这是否意味着一个地图对象只能被使用一次,之后它就会变成一个空列表?
Py3中有没有其他具有相同特性的对象? (我试过
range()
,不行。)
非常感谢!!!
在Python3map
returns一个迭代器中:
https://docs.python.org/3/library/functions.html#map
并且迭代器可以(并且应该)只使用一次。请参阅有关迭代器的官方文档: https://docs.python.org/3/tutorial/classes.html#iterators
在您的情况下,您需要在创建时将 map
转换为 list
,这将解决您的问题:
counts = list(map(lambda x: [x.count('0'), x.count('1')], strs))
一旦迭代器用完(意味着完全迭代),就没有任何东西可以迭代了,所以第二次迭代不会产生任何结果。举个例子。
a = map(int,['1','2','3'])
for i in a:
print(i)
for i in a:
print(i)
这将输出:
1
2
3
每当你需要多次迭代一个迭代器时,把它变成一个列表(或其他类型的序列):
a = list(map(int,['1','2','3']))
这输出:
1
2
3
1
2
3
当使用 sorted()
时,您也在迭代 map
迭代器对象:
a = map(int,['1','2','3'])
print(sorted(a)) # output: [1, 2, 3]
print(sorted(a)) # output: []
a = list(map(int,['1','2','3']))
print(sorted(a)) # output: [1, 2, 3]
print(sorted(a)) # output: [1, 2, 3]
根据文档:https://docs.python.org/3/library/functions.html#map
map(function, iterable, ...)
Return an iterator that applies function to every item of iterable, yielding the results.
map 的作用是 returns 一个迭代器,您可以对其进行迭代,但是一旦完成对它的迭代,它就会变空,或者当您继续对其进行迭代时,迭代器的大小会不断减小
因此,当您通过 sorted(counts, key=lambda x: x[0])
对 map(lambda x: [x.count('0'), x.count('1')], strs)
返回的迭代器 counts
进行迭代时,它变为空
为避免这种情况,您需要使用 list(map(...))
将任何要重复使用的迭代器转换为列表,然后您可以随意使用它,例如。
In [1]: strs = ["111", "1000", "1000", "1000"]
In [2]: counts = list(map(lambda x: [x.count('0'), x.count('1')], strs))
In [3]: counts)
Out[3]: [[0, 3], [3, 1], [3, 1], [3, 1]]
In [4]: cntSortBy0 = sorted(counts, key=lambda x: x[0])
In [5]: cntSortBy0
Out[5]: [[0, 3], [3, 1], [3, 1], [3, 1]]
In [6]: counts
Out[6]: [[0, 3], [3, 1], [3, 1], [3, 1]]
In [7]: cntSortBy1 = sorted(counts, key=lambda x: x[1])
In [9]: cntSortBy1
Out[9]: [[3, 1], [3, 1], [3, 1], [0, 3]]
In [10]: counts
Out[10]: [[0, 3], [3, 1], [3, 1], [3, 1]]
如您所见,我们使用了两次counts
,但它从来没有为空,因为我们现在将其转换为一个列表,即使您迭代了无数次,它仍然完好无损。