Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Group a list by word length

Tags:

python

list

For example, I have a list, say

list = ['sight', 'first', 'love', 'was', 'at', 'It']

I want to group this list by word length, say

newlist = [['sight', 'first'],['love'], ['was'], ['at', 'It']]

Please help me on it. Appreciation!

like image 822
Light Avatar asked Dec 04 '22 08:12

Light


2 Answers

Use itertools.groupby:

>>> from itertools import groupby
>>> lis = ['sight', 'first', 'love', 'was', 'at', 'It']
>>> [list(g) for k, g in groupby(lis, key=len)]
[['sight', 'first'], ['love'], ['was'], ['at', 'It']]

Note that for itertools.groupby to work properly all the items must be sorted by length, otherwise use collections.defaultdict(O(N)) or sort the list first and then use itertools.groupby(O(NlogN)). :

>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> lis = ['sight', 'first', 'foo', 'love', 'at', 'was', 'at', 'It']
>>> for x in lis:
...     d[len(x)].append(x)
...     
>>> d.values()
[['at', 'at', 'It'], ['foo', 'was'], ['love'], ['sight', 'first']]

If you want the final output list to be sorted too then better sort the list items by length and apply itertools.groupby to it.

like image 133
Ashwini Chaudhary Avatar answered Dec 16 '22 12:12

Ashwini Chaudhary


You can use a temp dictionary then sort by length:

li=['sight', 'first', 'love', 'was', 'at', 'It']

d={}
for word in li:
    d.setdefault(len(word), []).append(word)

result=[d[n] for n in sorted(d, reverse=True)] 

print result  
# [['sight', 'first'], ['love'], ['was'], ['at', 'It']]

You can use defaultdict:

from collections import defaultdict
d=defaultdict(list)
for word in li:
    d[len(word)].append(word)

result=[d[n] for n in sorted(d, reverse=True)] 
print result

or use __missing__ like so:

class Dicto(dict):
    def __missing__(self, key):
        self[key]=[]
        return self[key]

d=Dicto()
for word in li:
    d[len(word)].append(word)

result=[d[n] for n in sorted(d, reverse=True)] 
print result
like image 21
dawg Avatar answered Dec 16 '22 12:12

dawg