'Fill in uneven sized lists in Python
I have a 2D-List contains unequal size lengths, like this:
lst = [[1,2,3],[-1,2,4],[0,2],[2,-3,6]]
I use this code to insert a 0 if element size less 3:
newlist = [val.insert(1,0) for val in lst if len(val)<3]
But I just got an empty newlist and the original lst was inserted into a 0.
>>> lst = [[1,2,3],[-1,2,4],[0,2],[2,-3,6]]
>>> newlist = [val.insert(1,0) for val in lst if len(val)<3]
>>> newlist
[None]
>>> lst
[[1, 2, 3], [-1, 2, 4], [0, 0, 2], [2, -3, 6]]
I don't want use old lst list value because if modified value can return to newlist, I can directly use it convert to a DataFrame like this:
df = pd.DataFrame([val.insert(1,0) for val in lst if len(val)<3])
So, how do I do this? And I hope the code can be written in a one-liner.
Solution 1:[1]
You are getting None as the value for newlist because val.insert(1,0) returns None as the output.
Try this instead,
lst = [[1,2,3],[-1,2,4],[0,2],[2,-3,6]]
new_list = [i + [0] if len(i) < 3 else i for i in lst]
print(new_list)
Output -
[[1, 2, 3], [-1, 2, 4], [0, 2, 0], [2, -3, 6]]
Solution 2:[2]
The problem in your code is that val.insert(1,0) mutates the list in place, and returns None.
My suggestion is shown below. It might not be exactly the output you expected (because it returns an array of tuples), but it will probably serve for your purpose:
from itertools import zip_longest
list(zip(*zip_longest(*lst, fillvalue=0)))
# output:
# [(1, 2, 3), (-1, 2, 4), (0, 2, 0), (2, -3, 6)]
Explanation:
[zip_longest][1] aggregates elements from each sequence, and if they are of uneven length, missing values are filled-in with fillvalue. By using the * operator, each inner list is passed as a separate parameter to the function.
After zip_longest is done and missing are filled, I am zipping it again (the result was transposed by the first zip).
Solution 3:[3]
Keep things simple. Your original approach was valid, but just use a classical loop:
lst = [[1,2,3],[-1,2,4],[0,2],[2,-3,6]]
# if needed, keep a copy
# old_lst = lst.copy()
for l in lst:
if len(l)<3:
l.insert(1,0)
pd.DataFrame(lst)
Output:
0 1 2
0 1 2 3
1 -1 2 4
2 0 0 2
3 2 -3 6
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Zero |
| Solution 2 | |
| Solution 3 | mozway |
