Python Language
группа по()
Поиск…
Вступление
В Python метод itertools.groupby()
позволяет разработчикам группировать значения итерируемого класса на основе указанного свойства в другой итерируемый набор значений.
Синтаксис
- itertools.groupby (iterable, key = None или некоторая функция)
параметры
параметр | подробности |
---|---|
итерируемый | Любой python iterable |
ключ | Функция (критерии), по которой можно группировать итерацию |
замечания
groupby () является сложным, но общее правило, которое следует учитывать при его использовании, таково:
Всегда сортируйте элементы, которые хотите группировать, с тем же ключом, который вы хотите использовать для группировки
Рекомендуется, чтобы читатель взглянул на документацию здесь и посмотрел, как это объясняется с помощью определения класса.
Пример 1
Скажем, у вас есть строка
s = 'AAAABBBCCDAABBB'
и вы хотели бы разбить его так, чтобы все «A» были в одном списке и так со всеми «B» и «C» и т. д. Вы могли бы сделать что-то вроде этого
s = 'AAAABBBCCDAABBB'
s_dict = {}
for i in s:
if i not in s_dict.keys():
s_dict[i] = [i]
else:
s_dict[i].append(i)
s_dict
Результаты в
{'A': ['A', 'A', 'A', 'A', 'A', 'A'],
'B': ['B', 'B', 'B', 'B', 'B', 'B'],
'C': ['C', 'C'],
'D': ['D']}
Но для большого набора данных вы будете наращивать эти элементы в памяти. Здесь groupby () входит в
Мы могли бы получить тот же результат более эффективным образом, выполнив следующие
# note that we get a {key : value} pair for iterating over the items just like in python dictionary
from itertools import groupby
s = 'AAAABBBCCDAABBB'
c = groupby(s)
dic = {}
for k, v in c:
dic[k] = list(v)
dic
Результаты в
{'A': ['A', 'A'], 'B': ['B', 'B', 'B'], 'C': ['C', 'C'], 'D': ['D']}
Обратите внимание, что число «A» в результате, когда мы использовали группу, меньше фактического числа «A» в исходной строке. Мы можем избежать этой потери информации, сортируя элементы в s, прежде чем передавать их на c, как показано ниже
c = groupby(sorted(s))
dic = {}
for k, v in c:
dic[k] = list(v)
dic
Результаты в
{'A': ['A', 'A', 'A', 'A', 'A', 'A'], 'B': ['B', 'B', 'B', 'B', 'B', 'B'], 'C': ['C', 'C'], 'D': ['D']}
Теперь у нас есть все наши «А».
Пример 2.
В этом примере показано, как выбран ключ по умолчанию, если мы не укажем какой-либо
c = groupby(['goat', 'dog', 'cow', 1, 1, 2, 3, 11, 10, ('persons', 'man', 'woman')])
dic = {}
for k, v in c:
dic[k] = list(v)
dic
Результаты в
{1: [1, 1],
2: [2],
3: [3],
('persons', 'man', 'woman'): [('persons', 'man', 'woman')],
'cow': ['cow'],
'dog': ['dog'],
10: [10],
11: [11],
'goat': ['goat']}
Обратите внимание, что кортеж в целом считается одним из ключевых в этом списке
Пример 3.
Обратите внимание на этот пример, что мулато и верблюд не появляются в нашем результате. Появляется только последний элемент с указанным ключом. Последний результат для c фактически уничтожает два предыдущих результата. Но посмотрите новую версию, где у меня есть данные, отсортированные сначала на одном и том же ключе.
list_things = ['goat', 'dog', 'donkey', 'mulato', 'cow', 'cat', ('persons', 'man', 'woman'), \
'wombat', 'mongoose', 'malloo', 'camel']
c = groupby(list_things, key=lambda x: x[0])
dic = {}
for k, v in c:
dic[k] = list(v)
dic
Результаты в
{'c': ['camel'],
'd': ['dog', 'donkey'],
'g': ['goat'],
'm': ['mongoose', 'malloo'],
'persons': [('persons', 'man', 'woman')],
'w': ['wombat']}
Сортировка
list_things = ['goat', 'dog', 'donkey', 'mulato', 'cow', 'cat', ('persons', 'man', 'woman'), \
'wombat', 'mongoose', 'malloo', 'camel']
sorted_list = sorted(list_things, key = lambda x: x[0])
print(sorted_list)
print()
c = groupby(sorted_list, key=lambda x: x[0])
dic = {}
for k, v in c:
dic[k] = list(v)
dic
Результаты в
['cow', 'cat', 'camel', 'dog', 'donkey', 'goat', 'mulato', 'mongoose', 'malloo', ('persons', 'man', 'woman'), 'wombat']
{'c': ['cow', 'cat', 'camel'],
'd': ['dog', 'donkey'],
'g': ['goat'],
'm': ['mulato', 'mongoose', 'malloo'],
'persons': [('persons', 'man', 'woman')],
'w': ['wombat']}
Пример 4.
В этом примере мы видим, что происходит, когда мы используем разные типы итераций.
things = [("animal", "bear"), ("animal", "duck"), ("plant", "cactus"), ("vehicle", "harley"), \
("vehicle", "speed boat"), ("vehicle", "school bus")]
dic = {}
f = lambda x: x[0]
for key, group in groupby(sorted(things, key=f), f):
dic[key] = list(group)
dic
Результаты в
{'animal': [('animal', 'bear'), ('animal', 'duck')],
'plant': [('plant', 'cactus')],
'vehicle': [('vehicle', 'harley'),
('vehicle', 'speed boat'),
('vehicle', 'school bus')]}
Этот пример ниже, по существу, такой же, как и над ним. Единственное различие заключается в том, что я изменил все кортежи на списки.
things = [["animal", "bear"], ["animal", "duck"], ["vehicle", "harley"], ["plant", "cactus"], \
["vehicle", "speed boat"], ["vehicle", "school bus"]]
dic = {}
f = lambda x: x[0]
for key, group in groupby(sorted(things, key=f), f):
dic[key] = list(group)
dic
Результаты
{'animal': [['animal', 'bear'], ['animal', 'duck']],
'plant': [['plant', 'cactus']],
'vehicle': [['vehicle', 'harley'],
['vehicle', 'speed boat'],
['vehicle', 'school bus']]}