[英]Why does the map object in Python 3 need to be cast to a list to function with comprehension?
This question comes from a hackerrank question from basic data types. 这个问题来自基本数据类型的hackerrank问题。 When I run
当我跑步
max(map(int, range(5)))
I get the right output of 4, however when I do 我得到正确的输出4,但是当我这样做时
if __name__ == '__main__':
n = int(input()) #this line seems irrelevant to my question, but it was present in the original question so I have included it here for completeness
arr = map(int, input().split())
print(max([x for x in arr if x < max(arr)]))
and give input 并输入
5
2 3 6 6 5
the result is 2. However if I first cast the map object to a list I get the correct answer of 5. This is further bewildering as when I replace the print argument with 结果是2。但是,如果我首先将map对象转换为列表,则会得到正确的答案5。这进一步令人困惑,因为当我将print参数替换为
print(max(arr))
it gives the correct answer of 6, so clearly max works, but I'm guessing something in the list comprehension breaks on map objects for some reason. 它给出正确的答案6,因此max显然很有效,但是由于某种原因,我猜测列表对象中的某些理解会中断。 This is especially supported by the fact that if I do
如果我这样做,这一点尤其得到支持
print([x for x in arr if x < max(arr)])
I get 2. More testing with other less ordered lists shows that the last statement seems to always return list(arr)[0], so ultimately I expect the issue is with the list comprehension on the map objects. 我得到2。使用其他排序较少的列表进行的更多测试表明,最后一条语句似乎总是返回list(arr)[0],因此最终我希望问题出在对地图对象的列表理解上。 So ultimately what I'd like to know is
所以最终我想知道的是
The return value of map
in Python 3 is not a list, but an iterable object. Python 3中
map
的返回值不是列表,而是一个可迭代的对象。 It can easily be turned into a list, but if you use it directly, it can't be iterated multiple times. 可以轻松地将其转换为列表,但是如果直接使用它,则不能多次迭代。 If you iterate it once in order for
max
to be calculated, you have used it up, and you won't get all the items again. 如果对它进行一次迭代以便计算出
max
,则说明它已经用完,并且不会再得到所有项目。
In Python 2, map
built a list for you, so you didn't get the option of lazily evaluating the items inside it. 在Python 2中,
map
为您构建了一个列表,因此您没有选择延迟评估其中的项目。 In Python 3, you can pass it to the list
function to get a list. 在Python 3中,您可以将其传递给
list
函数以获取列表。
In Python 3, map
gives you an iterator . 在Python 3中,
map
提供了一个迭代器 。 So arr
gives you the numbers 2, 3, 6, 6 and 5 once . 所以
arr
为您提供了数字2,3,6,6和5 次 。 When you do [x for x in arr if x < max(arr)]))
, the for x in arr
asks arr
for its next element, which is 2
, and assigns that to x
. 当你
[x for x in arr if x < max(arr)]))
将for x in arr
要求arr
为它的下一个元件,它是2
,并且分配该至x
。 Then the max(arr)
goes over the remaining numbers (3, 6, 6 and 5) and returns the maximum, which is 6
. 然后,
max(arr)
遍历其余的数字max(arr)
和5)并返回最大值,即6
。 Since 2
is less than 6
, it ends up in your result. 由于
2
小于6
,因此最终得到结果。 Then the for x in arr
goes again, and since arr
already went through everything, we're finished. 然后
for x in arr
的for x in arr
再次出现,由于arr
已经经历了所有事情,所以我们完成了。 So that's why your result is [2]
. 这就是为什么您的结果是
[2]
。
You're wrong about the list always containing the first element, though. 但是,您对于总是包含第一个元素的列表是错误的。 If you for example enter
4 3 2 1
, then the resulting list is empty (because 4
isn't less than the maximum of 3, 2 and 1). 例如,如果输入
4 3 2 1
,则结果列表为空 (因为4
不小于3、2和1的最大值)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.