This question comes from a hackerrank question from basic data types. When I run
max(map(int, range(5)))
I get the right output of 4, however when I do
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
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. 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. 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. 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.
In Python 2, map
built a list for you, so you didn't get the option of lazily evaluating the items inside it. In Python 3, you can pass it to the list
function to get a list.
In Python 3, map
gives you an iterator . So arr
gives you the numbers 2, 3, 6, 6 and 5 once . 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
. Then the max(arr)
goes over the remaining numbers (3, 6, 6 and 5) and returns the maximum, which is 6
. Since 2
is less than 6
, it ends up in your result. Then the for x in arr
goes again, and since arr
already went through everything, we're finished. So that's why your result is [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).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.