Reduce list of lists if entries match
Question: I have a list in python which looks like

    
    
    [['boy','121','is a male child'],['boy','121','is male'],['boy','121','is a child'],['girl','122','is a female child'],['girl','122','is a child']]
    

I want to reduce the list based on the first 2 entries in each list, to get

    
    
    [['boy','121',is a male child, is male, is a child'],['girl','122','is a female child','is a child']]
    

is there a way to do this efficiently without creating a dummy list?


Answer: As a more pythonic way for such task you can use a dictionary :

    
    
    >>> li=[['boy','121','is a male child'],['boy','121','is male'],['boy','121','is a child'],['girl','122','is a female child'],['girl','122','is a child']]
    >>> 
    >>> d={}
    >>> 
    >>> for i,j,k in li:
    ...   d.setdefault((i,j),[]).append(k)
    ... 
    >>> d
    {('boy', '121'): ['is a male child', 'is male', 'is a child'], ('girl', '122'): ['is a female child', 'is a child']}
    

> [**setdefault(key[,
> default])**](https://docs.python.org/2/library/stdtypes.html#dict.setdefault)
>
> If key is in the dictionary, return its value. If not, insert key with a
> value of default and return default. default defaults to None.

And if you want to have the elements within 1 container you can loop over the
items and convert the value to `tuple` then ad it with key:

    
    
    >>> [i+tuple(j) for i,j in d.items()]
    [('boy', '121', 'is a male child', 'is male', 'is a child'), ('girl', '122', 'is a female child', 'is a child')]
    

As @jonrsharpe says as a more elegant way you can also use
`collections.defaultdict` :

    
    
    >>> from collections import defaultdict
    >>> 
    >>> d=defaultdict(list)
    >>> for i,j,k in li:
    ...   d[i,j].append(k)
    ... 
    >>> d
    defaultdict(<type 'list'>, {('boy', '121'): ['is a male child', 'is male', 'is a child'], ('girl', '122'): ['is a female child', 'is a child']})
    

