Я не смог найти понятного объяснения того, как на самом деле использовать itertools.groupby()
функцию Python . То, что я пытаюсь сделать, это:
- Возьмите список - в этом случае дети объективированного
lxml
элемента - Разделите его на группы по некоторым критериям
- Затем выполните итерацию по каждой из этих групп отдельно.
Я просмотрел документацию и примеры , но у меня возникли проблемы при попытке применить их за пределы простого списка цифр.
Итак, как мне использовать itertools.groupby()
? Есть ли другая техника, которую я должен использовать? Указатели на хорошее "предварительное" чтение также приветствуются.
Ответы:
ВАЖНОЕ ПРИМЕЧАНИЕ: сначала нужно отсортировать данные .
Часть, которую я не получил, - это то, что в примере конструкции
k
является текущим ключом группировки иg
является итератором, который можно использовать для перебора группы, определенной этим ключом группировки. Другими словами, самgroupby
итератор возвращает итераторы.Вот пример этого, используя более ясные имена переменных:
Это даст вам вывод:
В этом примере
things
это список кортежей, где первый элемент в каждом кортеже - это группа, к которой принадлежит второй элемент.groupby()
Функция принимает два аргумента: (1) данные для группы и (2) функцию к группе его с.Здесь
lambda x: x[0]
указываетсяgroupby()
использовать первый элемент в каждом кортеже в качестве ключа группировки.В приведенном выше
for
оператореgroupby
возвращает три пары (ключ, групповой итератор) - один раз для каждого уникального ключа. Вы можете использовать возвращенный итератор для перебора каждого отдельного элемента в этой группе.Вот немного другой пример с теми же данными, используя понимание списка:
Это даст вам вывод:
источник
groupby(sorted(my_collection, key=lambda x: x[0]), lambda x: x[0]))
в предположении, чтоmy_collection = [("animal", "bear"), ("plant", "cactus"), ("animal", "duck")]
вы хотите сгруппироватьanimal or plant
Пример на документации по Python довольно прост:
Таким образом, в вашем случае data - это список узлов,
keyfunc
куда идет логика функции вашего критерия, а затемgroupby()
группирует данные.Вы должны быть осторожны, чтобы отсортировать данные по критериям, прежде чем позвонить,
groupby
иначе это не сработает.groupby
Метод на самом деле просто перебирает список и всякий раз, когда ключ меняется, он создает новую группу.источник
keyfunc
и говорили: «Да, я точно знаю, что это такое, потому что эта документация довольно проста». Невероятно!itertools.groupby
это инструмент для группировки предметов.Из документов мы узнаем, что это может сделать:
groupby
объекты дают пары ключей-групп, где группа является генератором.особенности
Сравнения
Пользы
Примечание: некоторые из последних примеров взяты из PyCon (выступления) Виктора Террона (на испанском языке) «Кунг-фу на рассвете с Itertools». Смотрите также
groupby
исходный код, написанный на C.* Функция, в которой все элементы передаются и сравниваются, влияя на результат. Другие объекты с основными функциями включают в себя
sorted()
,max()
иmin()
.отклик
источник
[''.join(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D
.list()
,tuple()
) или использованы в цикле / понимании для отображения содержимого. Это избыточности, которые автор, скорее всего, исключил для экономии места.Отличный трюк с groupby - запустить кодирование длины в одну строку:
даст вам список из двух кортежей, где первый элемент - это символ, а второй - количество повторений.
Изменить: Обратите внимание, что это то, что отличает семантику
itertools.groupby
SQLGROUP BY
: itertools не (и вообще не может) заранее сортировать итератор, поэтому группы с одинаковым «ключом» не объединяются.источник
Другой пример:
результаты в
Обратите внимание, что igroup является итератором (подитератором, как его называет документация).
Это полезно для разбиения генератора на части:
Еще один пример группового - когда ключи не отсортированы. В следующем примере элементы в xx сгруппированы по значениям в yy. В этом случае сначала выводится один набор нулей, затем набор единиц, а затем снова набор нулей.
Производит:
источник
ПРЕДУПРЕЖДЕНИЕ:
Список синтаксиса (groupby (...)) не будет работать так, как вы хотите. Кажется, он уничтожает внутренние объекты итератора, поэтому
будет производить:
Вместо списка (groupby (...)) попробуйте [(k, list (g)) для k, g в groupby (...)], или, если вы часто используете этот синтаксис,
и получить доступ к функциональности groupby, избегая этих надоедливых (для маленьких данных) итераторов вместе.
источник
Я хотел бы привести еще один пример, где groupby без сортировки не работает. Адаптировано из примера Джеймса Сулака
выход
есть две группы с транспортным средством, тогда как можно ожидать только одну группу
источник
@CaptSolo, я попробовал твой пример, но он не сработал.
Вывод:
Как видите, есть два «О» и «2», но они попали в отдельные группы. Именно тогда я понял, что вам нужно отсортировать список, переданный функции groupby. Итак, правильное использование будет:
Вывод:
Просто помните, что если список не отсортирован, функция группировки не будет работать !
источник
источник
Вы можете использовать groupby, чтобы группировать вещи для повторения. Вы даете groupby итерируемую и необязательную ключевую функцию / вызываемую функцию, с помощью которой проверяются элементы, когда они выходят из итерируемой, и она возвращает итератор, который дает двукратный набор результата вызываемой клавиши и фактических элементов в еще один повторяемый. Из справки:
Вот пример группирования с использованием сопрограммы для группировки по счетчику, он использует вызываемый ключ (в данном случае
coroutine.send
), чтобы просто подсчитать счетчик для сколь угодно большого количества итераций и сгруппированный суб-итератор элементов:печать
источник
Может пригодиться один полезный пример:
Пример ввода: 14445221
Пример выборки: (1,1) (3,4) (1,5) (2,2) (1,1)
источник
Эта базовая реализация помогла мне понять эту функцию. Надеюсь, это поможет и другим:
источник
Вы можете написать собственную групповую функцию:
источник