Python: how to group a list of objects by their characteristics or attributes?

I want to highlight a list of objects in sublists, where objects with the same attributes / characteristics remain in the same sublist.

Suppose we have a list of strings:

["This", "is", "a", "sentence", "of", "seven", "words"]

We want to separate the lines based on their length as follows:

[['sentence'], ['a'], ['is', 'of'], ['This'], ['seven', 'words']]

The program that I just invented is

sentence = ["This", "is", "a", "sentence", "of", "seven", "words"]
word_len_dict = {}
for word in sentence:
    if len(word) not in word_len_dict.keys():
        word_len_dict[len(word)] = [word]
    else:
        word_len_dict[len(word)].append(word)


print word_len_dict.values()

I want to know if there is a better way to achieve this?

+4
source share
7 answers

Take a look at itertools.groupby(). Note that your list should be sorted first (more expensive than your OP method).

>>> from itertools import groupby
>>> l = ["This", "is", "a", "sentence", "of", "seven", "words"]
>>> print [list(g[1]) for g in groupby(sorted(l, key=len), len)]
[['a'], ['is', 'of'], ['This'], ['seven', 'words'], ['sentence']]

or if you want a dictionary →

>>> {k:list(g) for k, g in groupby(sorted(l, key=len), len)}
{8: ['sentence'], 1: ['a'], 2: ['is', 'of'], 4: ['This'], 5: ['seven', 'words']}
+5
source

defaultdict(list) :

from collections import defaultdict

word_len_dict = defaultdict(list)

for word in sentence:
    word_len_dict[len(word)].append(word)
+2

itertools.groupby , .

keyfunc = lambda x: len(x)
data = ["This", "is", "a", "sentence", "of", "seven", "words"]
data = sorted(data, key=keyfunc)
groups = []
for k, g in groupby(data, keyfunc):
    groups.append(list(g))
print groups
+1

, , . ( imo) .

list_ = ["This", "is", "a", "sentence", "of", "seven", "words"]

# for python 2 filter returns() a list
result = filter(None,[[x for x in list_ if len(x) == i] for i in range(len(max(list_, key=lambda y: len(y)))+1)])

# for python 3 filter() returns an iterator
result = list(filter(None,[[x for x in list_ if len(x) == i] for i in range(len(max(list_, key=lambda y: len(y)))+1)]))
0
sentence = ["This", "is", "a", "sentence", "of", "seven", "words"]
getLength = sorted(list(set([len(data) for data in sentence])))

result = []

for length in getLength:
    result.append([data for data in sentence if length == len(data)])

print(result)
0

dict setdefault:

sentence = ["This", "is", "a", "sentence", "of", "seven", "words"]
word_len_dict = {}
for word in sentence:
    word_len_dict.setdefault(len(word), []).append(word)

, setdefault , len(word) , , . setdefault - , .

, , , , setdefault , . , , setdefault.

0

, , :

data = ["This", "is", "a", "sentence", "of", "seven", "words"]
# Get all unique length values
unique_length_vals = set([len(word) for word in data])
# Get lists of same-length words
res = [filter(lambda x: len(x) == lval, data) for lval in unique_length_vals]

, , - .

0

Source: https://habr.com/ru/post/1653183/


All Articles