Nested list construction from df

I have a df like this.

df=pd.DataFrame({'Number':[1,2,3,4,5, 6, 7, 8, 9, 10, 11],
             'Name':['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'K', 'L'],
             'Value': [223, 124, 434, 514, 821, 110, 321, 211, 764, 123, 131]})

In my real world problem the df comes in different lengths and I need to transform them to a nested list with a certain characteristic to be able to create tables for pdf. I need a nested list where one list represents one row in the table. In this case I want the table to have four rows. And I want from the df to add four rows (df rows) to one table row. But if the df is larger, then I would have to increase both the number of lists (tables rows) and the ammont of df rows that goes to one table row.

# Expected output
[[1, 'A', 223, 5, 'E', 821, 9, 'I', 764],
 [2, 'B', 124, 6, 'F', 110, 10, 'K', 123],
 [3, 'C', 434, 7, 'G', 321, 11, 'L', 131],
 [4, 'D', 514, 8, 'H', 211]]

That list can be created like this. But I look for an more automated solution of course.

lst=[]

# Row 1
l1=df.iloc[0].tolist()
l2=df.iloc[4].tolist()
l3=df.iloc[8].tolist()
l1.extend(l2)
l1.extend(l3)
lst.append(l1)

# Row 2
l1=df.iloc[1].tolist()
l2=df.iloc[5].tolist()
l3=df.iloc[9].tolist()
l1.extend(l2)
l1.extend(l3)
lst.append(l1)

#Row 3
l1=df.iloc[2].tolist()
l2=df.iloc[6].tolist()
l3=df.iloc[10].tolist()
l1.extend(l2)
l1.extend(l3)
lst.append(l1)

#Row 4
l1=df.iloc[3].tolist()
l2=df.iloc[7].tolist()
l1.extend(l2)
lst.append(l1)

Solution 1:

how about this?

import pandas as pd
df = pd.DataFrame({'Number': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
                   'Name': ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'K', 'L'],
                   'Value': [223, 124, 434, 514, 821, 110, 321, 211, 764, 123, 131]})

df_list = df.values.tolist()
no_rows = 4
res = []
for i in range(no_rows):
    res.append([num for sublist in df_list[i::no_rows] for num in sublist])
res

Output:

>>>  [[1, 'A', 223, 5, 'E', 821, 9, 'I', 764],
      [2, 'B', 124, 6, 'F', 110, 10, 'K', 123],
      [3, 'C', 434, 7, 'G', 321, 11, 'L', 131],
      [4, 'D', 514, 8, 'H', 211]]

Solution 2:

I use defaultdict to be able to extend a list. Please read about defaultdict here: https://docs.python.org/3/library/collections.html#collections.defaultdict

import pandas as pd
from collections import defaultdict


def nested_list(df, rows):
    lst = df.values.tolist()
    new_lst = defaultdict(list)
    for i, ele in enumerate(lst):
        new_lst[i%rows].extend(ele)
    return list( new_lst.values() )

df=pd.DataFrame({'Number':[1,2,3,4,5, 6, 7, 8, 9, 10, 11],
             'Name':['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'K', 'L'],
             'Value': [223, 124, 434, 514, 821, 110, 321, 211, 764, 123, 131]})


lst = nested_list(df, rows=4)

'''
>>> lst
[[1, 'A', 223, 5, 'E', 821, 9, 'I', 764],
 [2, 'B', 124, 6, 'F', 110, 10, 'K', 123],
 [3, 'C', 434, 7, 'G', 321, 11, 'L', 131],
 [4, 'D', 514, 8, 'H', 211]]
 '''