Home > Blockchain >  Fill in uneven sized lists in Python
Fill in uneven sized lists in Python

Time:04-22

I have a 2D-List contains unequal size numers, 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.

CodePudding user response:

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).

CodePudding user response:

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]]

CodePudding user response:

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
  • Related