Reputation: 25
I'm new to Python and I'm having trouble with a problem I have for homework. The homework question is as follows:
Implement function evenrow() that takes a two-dimensional list of intergers and returns True if each row of the table sums up to an even number and False otherwise (i.e., if some row sums up to an odd number)
This is what the result should be:
evenrow([[1,3], [2,4], [0,6]])
True
evenrow([[1,3], [3,4], [0,5]])
False
Here's what my function looks like as of right now:
def evenrow(lst):
mysum = 0
for i in lst:
mysum += sum(i)
if mysum % 2 == 0:
return True
else:
if mysum %2 ==1:
return False
For some reason my function keeps giving me True no matter what I input. Is there anything I'm overlooking? Any hints would be greatly appreciated!
Upvotes: 0
Views: 1884
Reputation: 365657
I think Joran Beasley's answer is the most appropriate for your current level of knowledge, but it's worth seeing a more pythonic, higher-order way to solve the problem:
def even2d(list2d):
return all(sum(row) % 2 == 0 for row in list2d)
You probably won't understand this right off the bat, but I think I can explain it.
First, the all
function just returns True
if every value in a sequence is true. That's pretty obvious—plus, it avoids the need to "think backward" ("all rows are even unless one row is odd"). The trick is, what kind of sequence is that expression in the middle?
To start with, how would you get a sequence of row sums?
row_sums = []
for row in list2d:
row_sum = sum(row)
row_sums.append(row_sum)
Python lets you abbreviate this pattern in a list comprehension:
row_sums = [sum(row) for row in list2d]
And of course that expression sum(row)
can be something more complicated, like sum(row) % 2 == 0
:
row_evens = [sum(row) % 2 == 0 for row in list2d]
So:
def even2d(list2d):
row_evens = [sum(row) % 2 == 0 for row in list2d]
return all(row_evens)
Now we're almost done, but you can make it even better by using a generator expression, which gives you a sort of "lazy list", where the values aren't calculated until you need them. All you have to do is turn the square brackets into parentheses:
def even2d(list2d):
row_evens = (sum(row) % 2 == 0 for row in list2d)
return all(row_evens)
Upvotes: 3
Reputation: 50177
Once you return
from a method that's it, you can't "go back" through the loop. Instead, you should be returning False
if you find an odd row since once you find one don't need to check any more rows. Otherwise, if you've gone through all the rows and haven't found an odd then you know they're all even and can return True
.
def evenrow(lst):
for i in lst:
if sum(i) % 2 == 1:
return False
return True
Or if you're feeling cheeky see if you can figure out how this super short list comprehension version works:
def evenrow(lst):
return not len([x for x in lst if sum(x) % 2])
Upvotes: 2
Reputation: 113940
only check oddness in your even function to short circuit and return true at the end
def even2d(list2d):
for sub_list in list2d:
if sum(sub_list)%2 == 1:
return False
return True
vice versa for checking oddness
Upvotes: 5