user2055337
user2055337

Reputation: 25

Determining if sum of lists in 2D list is odd or even

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

Answers (3)

abarnert
abarnert

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

mVChr
mVChr

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

Joran Beasley
Joran Beasley

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

Related Questions