Minnie
Minnie

Reputation: 51

Python- Split List of tuples to sublist

I have a list of tuples as shown below. The tuples in the lists are dynamically stored. Let's say each tuple can have 6 elements or 20 elements. This count is dynamic.

a = [('Index','col1','col2','col3','col4','col5'),('1','2','4','6','78','9'),('3','6','8','9','2','1')]

I want to split first 3 elements from each tuple in a list to another list(like below).

b = [('Index','col1','col2'),('1','2','4'),('3','6','8')]
c = [('col3','col4','col5'),('6','78','9'),('9','2','1')]

Example2:

tup=[(7,6,8,19,2,4,13,1,10,25,11,34),(1,2,3,4,5,6,7,8,9,10,11,12),(3,5,6,7,89,0,1,3,4,5,6,7)]

Output should be like this-

 [(7,6,8),(1,2,3)(3,5,6)]
 [(19,2,4),(4,5,6),(7,89,0)]
 [(13,1,10),(7,8,9),(1,3,4)]
 [(25,11,34),(10,11,12),(5,6,7)]

Any suggestions on how this can be achieved in python?

Upvotes: 1

Views: 962

Answers (5)

DarrylG
DarrylG

Reputation: 17156

One liner that handles dynamic lists and different sizes.

def split_by(lst, size=3):
  return [[t[ind:ind+size] for t in a] for ind in range(0, min(map(len, a)), size)]

print(split_by(a))

Output

[   [('Index', 'col1', 'col2'), ('1', '2', '4'), ('3', '6', '8')],    
    [('col3', 'col4', 'col5'), ('6', '78', '9'), ('9', '2', '1')]]

Upvotes: 0

sardok
sardok

Reputation: 1116

My solution:

def split_by(tuples, size=3):
    lens = [len(t) for t in tuples]
    n = min(lens)
    cnt = 0
    while cnt < n:
        result = [t[cnt:cnt+size] for t in tuples]
        yield result
        cnt += size

Upvotes: 1

Marsilinou Zaky
Marsilinou Zaky

Reputation: 1047

A more flexible way that would work if the data size change

a = [('Index','col1','col2','col3','col4','col5'),('1','2','4','6','78','9'),('3','6','8','9','2','1')]
res = [[a[0][c:c+3], a[1][c:c+3], a[2][c:c+3]] for c in range(0,len(a[0]), 3)]
print(*res)
# [('Index', 'col1', 'col2'), ('1', '2', '4'), ('3', '6', '8')] [('col3', 'col4', 'col5'), ('6', '78', '9'), ('9', '2', '1')]

Solution 2: Taking into account different tuple sizes, so only iterate on multiple of 3 based on the shortest tuple as @Diego Palacios mentioned ;)

a = [('Index','col1','col2','col3','col4','col5','Extra'),('1','2','4','6','78','9', 'Extra'),('3','6','8','9','2','1')]
res = [[a[0][c:c+3], a[1][c:c+3], a[2][c:c+3]] for c in range(0,min(len(a[0]),len(a[1]),len(a[2]))//3*3, 3)]
print(*res)

Upvotes: 0

oppressionslayer
oppressionslayer

Reputation: 7204

You can use pandas to do this as well:

# pd.DataFrame(a).T.groupby(np.arange(len(pd.DataFrame(a).T))//3).agg(list).to_numpy().tolist() 
# [[['Index', 'col1', 'col2'], ['1', '2', '4'], ['3', '6', '8']],
# [['col3', 'col4', 'col5'], ['6', '78', '9'], ['9', '2', '1']]]

2nd Example:

tup=[(7,6,8,19,2,4,13,1,10,25,11,34),(1,2,3,4,5,6,7,8,9,10,11,12),(3,5,6,7,89,0,1,3,4,5,6,7)]

pd.DataFrame(tup).T.groupby(np.arange(len(pd.DataFrame(tup).T))//3).agg(list).to_numpy().tolist() 

output:

[[[7, 6, 8], [1, 2, 3], [3, 5, 6]],
 [[19, 2, 4], [4, 5, 6], [7, 89, 0]],
 [[13, 1, 10], [7, 8, 9], [1, 3, 4]],
 [[25, 11, 34], [10, 11, 12], [5, 6, 7]]]

Upvotes: 0

Diego Palacios
Diego Palacios

Reputation: 1144

You can use list comprehension and index slicing to get the job done:

if len(a[0]) > 3:
    b = [x[:3] for x in a]
    c = [x[3:] for x in a]

It may not be the fastest code, but it is very clear and simple.

Upvotes: 0

Related Questions