akhila mahadevan
akhila mahadevan

Reputation: 21

Combining lists according to their first element

i have a list say

 chain=[[0, 102], [1, 88], [1, 98],[1, 34],[2, 38], [2, 52],[2,15], [3, 26, 9],[3,5,6],[43, 88], [43, 98], [45, 100], [54, 9], [57, 26, 9], [62, 98]]

i want combine list starts with 0,1,2...etc into one by removing the repeated numbers, like [1,88,98,34], [2,38,52,15] ,[3,26,9,5,6]etc i have tried

c1=[]
c2=[]
for i in chain:
    for e in chain:       
        if(e!=i):
            if(i[0]==e[0]):
                c1=i
                c2=e
                c2.remove(c2[0])
                c1+=c2
                chain.remove(i)
                chain.remove(e)
                fam.append(c1)
 print(fam)

what i got is

 [[1, 88, 98], [2, 38, 52], [3, 26, 9, 5, 6], [16, 88, 98], [43, 88, 98]]

every time c1 get updated with i, it only combine two list....sorry if i am asking silly question.....please correct me.

Upvotes: 0

Views: 63

Answers (3)

dermen
dermen

Reputation: 5382

Try itertools.groupby

from itertools import groupby
some_groups = [(key, list(val)) 
               for key, val in groupby(chain, lambda x: x[0])]

#some_groups:
#[(0, [[0, 102]]),
# (1, [[1, 88], [1, 98], [1, 34]]),
# (2, [[2, 38], [2, 52], [2, 15]]),
# (3, [[3, 26, 9], [3, 5, 6]]),
# (43, [[43, 88], [43, 98]]),
# (45, [[45, 100]]),
# (54, [[54, 9]]),
# (57, [[57, 26, 9]]),
# (62, [[62, 98]])]

And then you can form the results as you wish

results = []
for key, groups in some_groups:
    unique_vals = set(  s for sublist in groups for s in sublist[1:]   )
    results.append( [key]+ list(unique_vals) )

#results:
#[[0, 102],
# [1, 88, 98, 34],
# [2, 52, 38, 15],
# [3, 9, 26, 5, 6],
# [43, 88, 98],
# [45, 100],
# [54, 9],
# [57, 9, 26],
# [62, 98]]

Update

It appears the result should only contain lists that were combined from 2 or more lists. This can be fixed by checking the length before appending

some_groups = [(key, list(val)) 
               for key, val in groupby(chain, lambda x: x[0])]
some_groups = [ (key,groups) for key,groups in some_groups if len(groups) > 1 ] #remove e.g. (0, [[0, 102]] ) from some_groups  

Upvotes: 3

Thane Plummer
Thane Plummer

Reputation: 10358

If you want one list of distinct items, you should consider set.

>>> chain=[[0, 102], [1, 88], [1, 98],[1, 34],[2, 38], [2, 52],[2,15], [3, 26, 9],[3,5,6],[43, 88], [43, 98], [45, 100], [54, 9], [57, 26, 9], [62, 98]]
>>> set(n for sublist in chain for n in sublist)
set([0, 1, 98, 3, 100, 38, 102, 9, 2, 34, 15, 6, 43, 52, 54, 57, 88, 45, 26, 62, 5])
>>> 

Upvotes: 0

TigerhawkT3
TigerhawkT3

Reputation: 49330

I recommend a dictionary.

result = {}
chain =  chain=[[0, 102], [1, 88], [1, 98],[1, 34],[2, 38], [2, 52],[2,15], [3, 26, 9],[3,5,6],[43, 88], [43, 98], [45, 100], [54, 9], [57, 26, 9], [62, 98]]
for item in chain:
    if item[0] in result:
        result[item[0]].append(item[1])
    else:
        result[item[0]] = [item[1]]

 

>>> print(*result.items(), sep='\n')
(0, [102])
(1, [88, 98, 34])
(2, [38, 52, 15])
(3, [26, 5])
(54, [9])
(57, [26])
(43, [88, 98])
(45, [100])
(62, [98])

If you want, you can turn this into a list:

result_list = [[k] + result[k] for k in sorted(result)]

 

>>> print(*result_list, sep='\n')
[0, 102]
[1, 88, 98, 34]
[2, 38, 52, 15]
[3, 26, 5]
[43, 88, 98]
[45, 100]
[54, 9]
[57, 26]
[62, 98]

Upvotes: 3

Related Questions