1
if __name__ == '__main__':
    arr = map(int, input().split())
    a = max([x for x in arr if x != max(arr)])
    print(a)

sample input: 1 2 3 4 5

goal here is to find second greatest number

type(max(arr)) is integer, each element type in arr when looping is integer, so why output isnt 4? This works perfectly only when I do arr = list(arr) but I want to know why wouldnt it work without it?

wjandrea
  • 28,235
  • 9
  • 60
  • 81
indiana505
  • 13
  • 2
  • In addition to what's said in the answers, a list comprehension like `[int(x) for x in inp.split()]` is almost always a better choice than `map`. – gog Dec 11 '22 at 23:52
  • Better solutions: [Get the second largest number in a list in linear time](/q/16225677/4518341) – wjandrea Dec 11 '22 at 23:54
  • 1
    @gog: When the mapping function is a built-in that already does what you need, there's no reason to prefer a listcomp over `map` (for built-ins implemented in C, the `map` will be slightly faster on a per-item basis, and shorter, and when you don't need the result as a `list` anyway, you're just iterating it once, lower latency and higher memory efficiency). – ShadowRanger Dec 11 '22 at 23:57
  • @ShadowRanger: `map` has its uses, but this is not one of them. – gog Dec 12 '22 at 00:04
  • 1
    @gog: There's nothing inherently terrible about using `list(map(int, input().split()))` (or `[*map(int, input().split())]`) instead of `[int(x) for x in input().split()]`. `map` is a strictly bad idea if you need a `lambda` to use it (where a listcomp or genexpr could inline it and avoid the function call entirely), but there's *nothing* wrong with `map` here. – ShadowRanger Dec 12 '22 at 00:13
  • "I value readability and usefulness for real code. There are some places where map() and filter() make sense, and for other places Python has list comprehensions" -- https://developers.slashdot.org/story/13/08/25/2115204/interviews-guido-van-rossum-answers-your-questions – gog Dec 12 '22 at 00:26

2 Answers2

2

map returns an iterator so it can only be consumed once. The first call to max(arr) in the first iteration already consumes it for every subsequent iteration.

If you want the second largest number, just sort the array and get the second (or second-to-last, depending on how you order). This will also give you a O(nlogn) solution instead of the (potentially) O(n^2) solution that you have attempted to write.

DeepSpace
  • 78,697
  • 11
  • 109
  • 154
1

The problem is that arr is an iterator, and you can only go through an iterator once.

You start off with [x for x in arr...] and x gets the value 1. You then take max(arr), and that's going to see the item 2, 3, 4, 5 and then use all of them up. It will return 5, but now the iterator is empty. Your outer [...] now sees that there are no more elements to look at, and returns max(1) = 1.

Frank Yellin
  • 9,127
  • 1
  • 12
  • 22