I have the output of a Markov transition table, which is a list of 59 lists each with 59 floats. I want to invert each of the non-0 floats, and then normalise the output so that again I have a list of probabilities which add up to 1.
I have read the textbook on list comprehensions, and that seems relevant, but I can't for the life of me understand how to implement it.
The list of lists is m
for i in range(59):
[1/item for item in m[i] if item > 0.]
i += 1
This runs, but it doesn't change m
. Am I wrong to be using item
in this code? Should I be using some other reference?
[1/item for item in m[i] if item > 0.]
creates a new list. Then you do nothing with that list. What Graipher is telling you is that you need a reference to the newly created list: m[i] = <your list comprehension>
will assign back to row i
of your list of lists.
Also, consider numpy for element-wise operations. Demo:
>>> import numpy as np
>>> m = np.array([[1,2], [3, 0]])
>>> m = 1.0/m
>>> m
array([[ 1. , 0.5 ],
[ 0.33333333, inf]])
>>> m[m == np.inf] = 0
>>> m
array([[ 1. , 0.5 ],
[ 0.33333333, 0. ]])
You need to assign it back to m[i]
in the loop:
for i in range(len(m)):
m[i] = [1./item if item != 0. else item for item in m[i]]
And the i+=1
is not needed because the for
loop does that for you.
In order to avoid the sublist being shorter than the original sublist, you need to move the if from the end of the list comprehension (which basically filters which items are processed) to the front (so the value itself is a ternary expression that evaluates to 1/item
or item
, depending on the value of item
).
At this point you should probably watch the presentation Loop like a Native and rewrite it for example as:
for i, x in enumerate(m):
m[i] = [1./item if item != 0. else item for item in x]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With