Reputation: 291
Right now I'm trying to get my program to take a two dimensional list as an input and return either true or false depending on whether or not it is "rectangular" (eg. [[2,3],[1,5],[6,9]] is rectangular whereas [[2,3],[1,8,6]] is not.) So far I've come up with this:
def rectangular(List):
n = List
for i in n:
if len(i) != len(n[0]):
return False
elif len(i) == len(n[0]):
i
I can't seem to figure out how to create a "true" case. Using the elif above I'm able to cycle through the list but if i were to add a return true portion it stops as soon as that is the case. Would a while loop work better in this case? All help is appreciated! Thanks.
Upvotes: 3
Views: 2767
Reputation: 366103
If you get to the end without finding a false case, then you know it's true, right? There aren't any other possibilities.
So, you can just remove the elif
entirely, and just add a return True
at the end:
def rectangular(List):
n = List
for i in n:
if len(i) != len(n[0]):
return False
return True
As a side note, your elif
that has exactly the opposite condition as the if
is better written as just else:
. That way, there's no chance of you getting the opposite condition wrong, no need for your readers to figure out that it's the opposite, etc.
Also, there's no reason to take the argument as List
, then bind the same value to n
and use that. Why not just take n
in the first place?
def rectangular(n):
for i in n:
if len(i) != len(n[0]):
return False
return True
You can make this more concise, and maybe more Pythonic, by replacing the for
statement with a generator expression and the all
function:
def rectangular(n):
return all(len(i) == len(n[0]) for i in n)
But really, this isn't much different from what you already have. You should learn how this works, but if you don't understand it yet, there's no problem doing it the more verbose way.
If you want to get clever:
def rectangular(n):
lengths = {len(i) for i in n}
return len(lengths) == 1
We're making a set of all of the lengths. Sets don't have duplicates, so this is a set of all of the distinct lengths. If there's only 1 distinct length, that means all of the lengths are the same.
However, note that for an empty list, this will return False
(because there are 0 lengths, not 1), while the other two will return True
(because a condition is vacuously true for all values if there are no values to test). I'm not sure which one you want, but it should be relatively easy to figure out how to change whichever one you choose to do the opposite.
Upvotes: 4
Reputation: 5383
You can make sure that the lengths of all elements of the list are the same length. Or in Python:
all(map(lambda m: len(m) == len(x[0]), x))
Where x
is what you want to check.
The only problem with this solution is that the if the list looks like [ [1,2], [1,[1,2]], 'ab' ]
, it is still going to return True
. So you additionally need to do some type checking.
Upvotes: 1
Reputation: 48835
Try using the all function with a generator:
def rectangular(lst):
first_len = len(lst[0])
# I used lst[1:] to skip the 0th element
return all(len(x) == first_len for x in lst[1:])
The all
function returns True
if all elements of an iterable are True
, and False
otherwise.
It's good that you didn't call your variable list
, but capitalized names usually represent a class in Python, so lst
is a better choice than List
.
NOTE: I made the assumption that "rectangular" means each sublist is the same length. If in reality each sublist should be (say) 2 elements long, just replace first_len
with the literal 2
and remove the [1:]
on lst[1:]
. You may also want to add some exception handling in case you pass a list with only one element.
Upvotes: 4