Перейти к основному содержимому

Группировка коллекции

Группировка означает раскладывание элементов по корзинам. Для каждого элемента вы выбираете ключ, и все элементы с одинаковым ключом попадают в одну корзину.

Ключ вычисляется небольшим выражением, которое принимает один элемент и возвращает его ключ. Например, первую букву слова.

У списков в Python нет встроенного метода group_by. Естественный способ группировки — словарь, ключи которого являются ключами групп, а значения — списками элементов. Его заполняют циклом for и методом setdefault() или поручают collections.defaultdict(list) создавать пустые списки за вас.

Словарь хранит записи в порядке добавления, поэтому группы появляются в том порядке, в котором встретились их первые элементы. Вывод всегда выглядит одинаково.


Группировка по ключу

Самая простая группировка оставляет элементы как есть и только решает, в какую корзину попадёт каждый из них.

setdefault(key, []) возвращает список, хранящийся под ключом, а если ключа ещё нет, сначала сохраняет под ним новый пустой список. Поэтому groups.setdefault(key, []).append(w) работает даже для первого элемента группы. Элементы внутри группы сохраняют порядок, который они имели во входных данных.

Иногда элементы нужно изменить при группировке, например сохранить их в верхнем регистре. Вычислите ключ, вычислите новое значение и добавьте новое значение в группу. С defaultdict(list) достаточно простого groups[key].append(value).

Группировка слов по первой букве

Ключ — первая буква слова, w[0], переведённая в верхний регистр с помощью upper(). Слова, начинающиеся с одной и той же буквы, оказываются в одном списке.

Prompt
Сгруппируйте слова one, two, three, four, five по их первой букве в верхнем регистре. Заполните словарь, сопоставляющий букве список слов, с помощью цикла и setdefault(). Выведите словарь.
Вывод: полная программа на Python
Group words by first letter

Группировка с изменением значений

Ключ — первая буква в нижнем регистре. Сохраняемое значение — всё слово в верхнем регистре. defaultdict(list) начинает каждую новую группу с пустого списка; dict() превращает его обратно в обычный словарь для аккуратного вывода.

Prompt
Сгруппируйте слова one, two, three, four, five по их первой букве в нижнем регистре. Сохраняйте каждое слово в его группе в верхнем регистре, а не в исходном виде. Используйте collections.defaultdict со списками, затем выведите его как обычный словарь.
Вывод: полная программа на Python
Group and change the values

Подсчёт в каждой группе

Часто элементы каждой группы не нужны — важно только, сколько их.

В стандартной библиотеке есть инструмент именно для этого: collections.Counter. Передайте ему ключи, и он вернёт похожий на словарь объект, сопоставляющий ключу количество. Чтение ключа, которого нет в Counter, даёт 0.

При выводе Counter показывает сначала самые большие количества.

Подсчёт слов по первой букве

Каждое слово превращается в свою первую букву, и Counter подсчитывает буквы. Буквы t и f встречаются по два раза, поэтому они выводятся перед o.

Prompt
Подсчитайте, сколько из слов one, two, three, four, five начинается с каждой буквы. Используйте collections.Counter для первых букв и выведите счётчик.
Вывод: полная программа на Python
Count words per first letter

Свёртка и накопление по группам

Свернуть группу — значит шаг за шагом объединить её элементы в одно значение. Классический пример — нарастающая сумма: начать с 0 и прибавлять каждый элемент.

В Python нет fold() или aggregate() для групп. Используйте словарь, который хранит текущее значение каждой группы. Для каждого элемента вычислите его ключ и обновите значение, хранящееся под этим ключом.

Если у текущего значения есть начальное значение, например 0 для суммы, get(key, 0) даёт это начальное значение для отсутствующего ключа. Если значение должен начинать сам первый элемент, проверьте оператором in, существует ли уже ключ; подойдёт и get(key), который для отсутствующего ключа даёт None.

Сумма каждой группы

Каждое число помещается в группу "even" или "odd" и прибавляется к сумме этой группы. sums.get(key, 0) начинает новый ключ с 0, поэтому особый случай не нужен.

Prompt
Возьмите числа 3, 4, 5, 6, 7, 8 и поместите каждое в группу "even" или "odd". Вместо того чтобы хранить числа, прибавляйте каждое число к нарастающей сумме его группы в словаре, используя get(key, 0) как начальное значение. Выведите словарь.
Вывод: полная программа на Python
Sum each group

Построение строки для каждой группы

Первое число группы начинает строку. Каждое следующее число присоединяется через "+". Проверка key not in chains различает эти два случая. str() превращает число в текст.

Prompt
Возьмите числа 3, 4, 5, 6, 7, 8 и поместите каждое в группу "even" или "odd". Для каждой группы постройте строку шаг за шагом: первое число начинает строку, а каждое следующее число добавляется со знаком "+" перед ним, так что получается текст вроде 3+5+7. Выведите словарь, сопоставляющий имени группы строку.
Вывод: полная программа на Python
Build a string per group