Поиск…


Вступление

В 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']]}


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow