-2
def evenchecker(lst):
    for number in lst:
        return number%2==0
    else:
        pass

I am trying to create a function that checks for an even number in the list or any iterable item for that matter. When I keep the first number as an even number it works but when I keep the first number as odd it falls apart, it just returns false and does not report true for the further even numbers.

Can somebody please explain why is this happening, I am an absolute beginner in programming and learning from a Udemy course. I did find a workaround for this,

def evenchecker(lst):
    for number in lst:
        if number%2==0:
            return "The list has an even number"
    else:
        pass

this checks on till the last number.

Gem
  • 99
  • 3
  • How do you conclude the facts that you claim? You are probably not examining the code correctly, but we can't tell what you are doing wrong just from the claims you make. – tripleee Mar 11 '21 at 05:57
  • @tripleee when I write evenchecker([1,2]) for the first function it says false, when it should say even because there is a even number in the list but when I do evenchecker([2,1]) it says True because the first element is an even number. For the second function I wrote, it can check for any number in the list,it doesn't stop at the first number only. – Gem Mar 11 '21 at 06:01
  • 3
    Are you aware that return *immediately* stops the function, and thus also any outer constructs such as loops? – MisterMiyagi Mar 11 '21 at 06:01
  • Understood now, thanks @MisterMiyagi – Gem Mar 11 '21 at 06:02
  • 1
    I would recommend that you go back and review the fundamentals about `if ... else` and `for`. – RajeshM Mar 11 '21 at 06:03

2 Answers2

5

Your first loop returns immediately. It's not going to look at any other parts of the list. Your second example does it properly. The

    else:
        pass

parts are absolutely useless. Remove them.

Note that you can do that operation in a single line:

def evenchecker(lst):
    return any(k % 2 == 0 for k in lst)
Tim Roberts
  • 48,973
  • 4
  • 21
  • 30
  • 1
    The code as shown will give different results if the input contains 0. – MisterMiyagi Mar 11 '21 at 06:09
  • Nice catch. I tweaked it. – Tim Roberts Mar 11 '21 at 06:59
  • 2
    Might be more intuitive to use `True` instead of `1`, even though any value for which bool(value) is `True` would suffice. – holdenweb Mar 11 '21 at 07:42
  • That's really personal preference, isn't it? For example, I tend to use `while 1:`, probably because of long years of C++ poisoning. – Tim Roberts Mar 11 '21 at 07:48
  • 2
    Maybe it's a personal preference. But in my opinion if you mean `True` then use `True`. – Matthias Mar 11 '21 at 07:52
  • 2
    @holdenweb For "intuitive", I'd go with `any(k % 2 == 0 for k in lst)`, which I think is the usual style. Though it's slower. – superb rain Mar 11 '21 at 20:42
  • Ah, @superbrain, that's actually what I meant to type. I don't know why my fingers didn't think of that. I've modified the answer. I don't think it is any slower at all. – Tim Roberts Mar 11 '21 at 21:54
  • @TimRoberts For example on ``lst = [1] * 1000 + [0]``, it's about factor 1.6 slower in [my benchmark](https://tio.run/##VY/RCsIwDEXf@xX3RdrqkM69iLAvkSETOi3armQZ6NfPZQPFvARy7k1u8pvvfaqOmaapoz6CQ/SBEWLuiUE@@5aVGjyPGTX0c@C5ncsGW5TOOexwdo1Wyr8yDYIU5tJtepsHNjigruHQ9YQHQsLst7r4aco/hNDh5xJho5QILiKgNt28qexpsctYjgpZjq9jKYkYQzJreiO0wPJCgTTGq6dasjtrv5ZMIbHRm33V6TkAF8vOla/MTtMH). Exercise left for reader: Explain why :-) – superb rain Mar 11 '21 at 22:06
  • [Tried a few more](https://tio.run/##lVJBTsMwELz7FXupbENUJSkHhJQrL@BWRVFoNtRq7Vj2FlE@H2xHNA0gAXuKZ2YzO6u1Z9oPZnNv3Tj2btBASqMiUNoOjsChxZYY80gnCxVwztnRU/jaFjXcQJHnOdzCNq9Zhz3gK5rdHncHdIUIOvnAIFQ/ODiAMhCgCYml@gCuoISqgnyGY7lg5ww8uROyq/dje/T41aj8i5EZaDL7h0/MyvDNOh/jJp635izmoRd@kmezplhQy6i/CC@jXnR5ZHVrRQnrpnF66JomW1h@2/sPRPlJ1IyRT5m2dXJv4v9T0Jpd3q41Lyg2V4uNigzIR/ZdWZE6IuDlvNV4GloZMR2OmHrS9WRgTvoZXRVvRsq5w69ba9F0gmbQOmVI3Ai@6njYhaB4a3gn0yAUJyAvszTS1DQ1yHH8AA), fastest ways are more than twice as fast on that, with a `for` statement being the fastest. – superb rain Mar 11 '21 at 22:30
  • You're a man after my own heart. Thanks for doing that -- really. Naturally the function should be faster, because it can short-circuit. It's just not as pretty... – Tim Roberts Mar 11 '21 at 22:52
  • @TimRoberts They're not faster because of short-circuiting. *All* of those solutions short-circuit. And in my test-list that doesn't even help, as the only even number is at the end. – superb rain Mar 11 '21 at 23:52
1

You have to differentiate between what the result of the function is and how you get there. What you want is to know whether the list contains an even number. That means that in either case, you have to iterate over all numbers in the list.

for number in lst:
       return number%2==0

Since return immediately returns a result, the function just tests whether the first element of the list is even or odd. This returns true if the first element is even.

However the original code (slightly modified)

for number in lst:
        if number%2==0:
            return true;
return false;

this checks, for every element in the list, whether the number is even (% is the modulo operator) and only then, it returns. So the "if" is very important here.

PMF
  • 14,535
  • 3
  • 23
  • 49