Reputation: 149
Python beginner here, I've literally spent several hours of what I assume is a grade school problem to most - but I finally managed to get a solution together.
The assignment was: Given a list of lists, such as L=[[1,2],[2,3,5]] I want to multiply by 5 all the odd numbers in L.
Eventually I came up with this, which miraculously worked:
def isOdd(n):
if n%2 != 0:
return True
else:
return False
def mult(L):
for i in L:
for j in i:
if isOdd(j):
oddInd = i.index(j)
i[oddInd] = j*5
print(L)
I hardly ever ask for homework help, but I feel okay about this one since I've already done it; the reason I'm writing this here is to know if there's a better and quicker way to get around this (I'm sure it can be done in 2 lines).
Also why wouldn't this work? (It was my first thought, and why I wasted so much time, before thinking about indices)
def mult(L):
for i in L:
for j in i:
if isOdd(j):
j = j*5
Thank you for your time everyone!
Upvotes: 0
Views: 100
Reputation: 5889
Your problem would be that you never actually modify L when iterating over it.
Use list comprehension
L=[[1,2],[2,3,5]]
newL = [[num*5 if num%2 !=0 else num for num in lst] for lst in L]
output
[[5, 2], [2, 15, 25]]
Upvotes: 0
Reputation: 170
Your first solution was good, but it failed in a couple of cases. If you input [[3,15]], you'll find that your solution outputs [[75,15]]. That's because when you assign the variable oddInd, you say i.index(j). That's an issue because index will only find the first instance of that value, meaning if there are multiple instances of value 'j' in the given list, you may get an undesired output like we saw. A solution is to write the function like this:
def mult(L):
for i in L:
for j in range(len(i)):
if isOdd(i[j]):
i[j] = i[j]*5
print(L)
In this solution, we find the length of the list 'i', and loop through that length, so that when we want to find the instance of that index, i[j] will find us that, without any chance of finding an incorrect instance like i.index(j) will. Prune also explained this well, I just wanted to give another solution and perspective
Upvotes: 0
Reputation: 77837
Your given solution is almost correct. Try it with a sub-list where a later element is 5 times a previous one, and you'll see a failure. For instance, simply L = [[1, 5]]
. The problem is that find
locates only the first instance of the value in the list, not the one you reference with j
. Instead ...
for oddIdx, j in enumerate(i):
if isOdd(j):
i[oddInd] = j*5
I deleted the rest of my answer, as BubbyBob
just covered the list comprehension.
Upvotes: 3