Piyush Patil
Piyush Patil

Reputation: 55

How to group a two dimensional list in python based on an attribute?

Example: Here is my 2D list:

a=[]
a.append(['abc.com','ars','league1','man'])
a.append(['abcxyz.com','hah','league2','bah'])
a.append(['abcd.com','gah','league3','fah'])
a.append(['abcm.com','ada','league1','ads'])
a.append(['abcxyzf.com','gha','league1','tra'])
a.append(['abcdg.com','jhi','league2','yui'])

What I want my output to be is:

print(a)
Output:
['abc.com','ars','league1','man']
['abcm.com','ada','league1','ads']
['abcxyzf.com','gha','league1','tra']
['abcxyz.com','hah','league2','bah']
['abcdg.com','jhi','league2','yui']
['abcd.com','gah','league3','fah']

That is I want to group my list depending on the attribute at index 2.

At least, I want the distinct values of column 3.

Upvotes: 2

Views: 1103

Answers (2)

jpp
jpp

Reputation: 164663

Your terminology is confusing: what you have in a is a list of lists rather than a list of tuples. However, this is not relevant in the solution provided below.

In addition, note that attributes are not involved here. We access list elements.

The classic Python way, which deals with both your questions (grouping and unique keys), is to use collections.defaultdict:

Setup

a = []
a.append(['data1','data2','data3','data4'])
a.append(['data21','data22','data3','data24'])
a.append(['data31','data32','data4','data34'])

Solution

from collections import defaultdict

d = defaultdict(list)

for item in a:
    d[item[2]].append(item)

Result

defaultdict(list,
            {'data3': [['data1', 'data2', 'data3', 'data4'],
                       ['data21', 'data22', 'data3', 'data24']],
             'data4': [['data31', 'data32', 'data4', 'data34']]})

Explanation

  • Initialise a default dictionary of lists.
  • Iterate your list of lists.
  • Append items to keys determined by the 3rd element.

Your sorted list format is then possible via sorted:

from operator import itemgetter
from itertools import chain

sorter = map(itemgetter(1), sorted(d.items()))
res = list(chain.from_iterable(sorter)))

[['data1', 'data2', 'data3', 'data4'],
 ['data21', 'data22', 'data3', 'data24'],
 ['data31', 'data32', 'data4', 'data34']]

sorter sorts items of the dictionary as if they were key-value tuples (so, since keys are unique, by key). itemgetter(1) extracts the second element of the result, i.e. the values.

chain.from_iterable is used to flatten nested lists in an efficient way.

Upvotes: 2

Keyur Potdar
Keyur Potdar

Reputation: 7238

Looks like you want to sort the list with the item at second index as the key.

a=[]
a.append(['abc.com','ars','league1','man'])
a.append(['abcxyz.com','hah','league2','bah'])
a.append(['abcd.com','gah','league3','fah'])
a.append(['abcm.com','ada','league1','ads'])
a.append(['abcxyzf.com','gha','league1','tra'])
a.append(['abcdg.com','jhi','league2','yui'])

a.sort(key=lambda k: k[2])
print(a)

Output:

[['abc.com', 'ars', 'league1', 'man'],
 ['abcm.com', 'ada', 'league1', 'ads'],
 ['abcxyzf.com', 'gha', 'league1', 'tra'],
 ['abcxyz.com', 'hah', 'league2', 'bah'],
 ['abcdg.com', 'jhi', 'league2', 'yui'],
 ['abcd.com', 'gah', 'league3', 'fah']]

Upvotes: 3

Related Questions