0

I am doing this problem:

Given an array of integers arr, a lucky integer is an integer which has a frequency in the array equal to its value. Return a lucky integer in the array. If there are multiple lucky integers return the largest of them. If there is no lucky integer return -1.

I am using this code, which works and passed all tests:

class Solution:
    def findLucky(self, arr: List[int]) -> int:
        values = [n for n in arr if n if arr.count(n) == n]
        return max(values) if values else -1

However, when I try to change the list comprehension to a generator expression like so:

class Solution:
    def findLucky(self, arr: List[int]) -> int:
        values = (n for n in arr if n if arr.count(n) == n)
        return max(values) if values else -1

I get this error:

Traceback (most recent call last):
  File "...", line 10, in <module>
    print(Solution().findLucky([2, 3, 4]))
  File "...", line 7, in findLucky
    return max(values) if values else -1
ValueError: max() arg is an empty sequence

Why does a list comprehension work whereas a generator expression fails?

I've tried converting the generator expression to a list in the comprehension, but that won't work because then the generator is exhuased.

Alan Bagel
  • 818
  • 5
  • 24

1 Answers1

3

Every generator is true, so you always call max(values) even if the generator is "empty". The right way to do it is to tell max what to do then:

return max(values, default=-1)
no comment
  • 6,381
  • 4
  • 12
  • 30
  • It's even a stretch to talk about a generator being "empty", as they aren't containers. They are *producers*, and the only way to tell if a generator will produce a value is to try to retrieve it via the iterator protocol. – chepner Sep 17 '21 at 14:05
  • @chepner Alright, put it in quotes, hopefully that's clear enough :-) – no comment Sep 17 '21 at 14:06