Não consegui encontrar uma explicação compreensível de como realmente usar a itertools.groupby()
função do Python . O que estou tentando fazer é o seguinte:
- Faça uma lista - neste caso, os filhos de um objeto
lxml
elemento - Divida-o em grupos com base em alguns critérios
- Depois, repita cada um desses grupos separadamente.
Revi a documentação e os exemplos , mas tive problemas para tentar aplicá-los além de uma simples lista de números.
Então, como eu uso itertools.groupby()
? Existe outra técnica que eu deveria estar usando? Indicadores para uma boa leitura de "pré-requisito" também serão apreciados.
Respostas:
NOTA IMPORTANTE: Você deve classificar seus dados primeiro.
A parte que eu não entendi é que na construção de exemplo
k
é a chave de agrupamento atual eg
é um iterador que você pode usar para iterar sobre o grupo definido por essa chave de agrupamento. Em outras palavras, ogroupby
próprio iterador retorna iteradores.Aqui está um exemplo disso, usando nomes de variáveis mais claros:
Isso fornecerá a saída:
Neste exemplo,
things
há uma lista de tuplas em que o primeiro item em cada tupla é o grupo ao qual o segundo item pertence.A
groupby()
função usa dois argumentos: (1) os dados para agrupar e (2) a função para agrupá-los.Aqui,
lambda x: x[0]
dizgroupby()
para usar o primeiro item em cada tupla como a chave de agrupamento.Na
for
instrução acima ,groupby
retorna três pares (chave, iterador de grupo) - uma vez para cada chave exclusiva. Você pode usar o iterador retornado para iterar sobre cada item individual nesse grupo.Aqui está um exemplo um pouco diferente com os mesmos dados, usando uma compreensão de lista:
Isso fornecerá a saída:
fonte
groupby(sorted(my_collection, key=lambda x: x[0]), lambda x: x[0]))
com a suposição de quemy_collection = [("animal", "bear"), ("plant", "cactus"), ("animal", "duck")]
você deseja agrupar eanimal or plant
O exemplo nos documentos do Python é bastante direto:
Portanto, no seu caso, dados são uma lista de nós,
keyfunc
é para onde a lógica da sua função de critérios vai e depoisgroupby()
agrupa os dados.Você deve ter o cuidado de classificar os dados pelos critérios antes de ligar
groupby
ou eles não funcionarão.groupby
Na verdade, o método itera através de uma lista e, sempre que a chave muda, ele cria um novo grupo.fonte
keyfunc
e ficou tipo "sim, eu sei exatamente o que é isso porque essa documentação é bastante direta". Incrível!itertools.groupby
é uma ferramenta para agrupar itens.A partir dos documentos , analisamos ainda mais o que isso pode fazer:
groupby
objetos produzem pares de grupos de chaves em que o grupo é um gerador.Recursos
Comparações
Usos
Nota: Vários dos exemplos anteriores derivam do PyCon de Víctor Terrón () (espanhol) , "Kung Fu ao amanhecer com ferramentas". Veja também o
groupby
código fonte escrito em C.* Uma função na qual todos os itens são passados e comparados, influenciando o resultado. Outros objetos com funções principais incluem
sorted()
,max()
emin()
.Resposta
fonte
[''.join(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D
.list()
,tuple()
) ou consumidos em um loop / compreensão para exibir o conteúdo. São redundâncias que o autor provavelmente excluiu para economizar espaço.Um truque neato com groupby é executar a codificação de comprimento em uma linha:
fornecerá uma lista de duas tuplas em que o primeiro elemento é o caractere e o segundo é o número de repetições.
Edit: Observe que é isso que separa
itertools.groupby
aGROUP BY
semântica do SQL : o itertools não (e geralmente não pode) classificar o iterador antecipadamente, para que grupos com a mesma "chave" não sejam mesclados.fonte
Outro exemplo:
resulta em
Observe que o igroup é um iterador (um sub-iterador como a documentação chama).
Isso é útil para dividir um gerador:
Outro exemplo de groupby - quando as chaves não estão classificadas. No exemplo a seguir, os itens em xx são agrupados por valores em yy. Nesse caso, um conjunto de zeros é emitido primeiro, seguido por um conjunto de unidades, seguido novamente por um conjunto de zeros.
Produz:
fonte
ATENÇÃO:
A lista de sintaxe (groupby (...)) não funcionará da maneira que você pretende. Parece destruir os objetos do iterador interno, portanto, usando
vai produzir:
Em vez de list (groupby (...)), tente [(k, list (g)) para k, g em groupby (...)] ou, se você usa essa sintaxe com frequência,
e tenha acesso à funcionalidade groupby, evitando os iteradores incômodos (para pequenos dados) todos juntos.
fonte
Eu gostaria de dar outro exemplo em que groupby sem classificação não está funcionando. Adaptado do exemplo por James Sulak
saída é
existem dois grupos com veículo, enquanto um poderia esperar apenas um grupo
fonte
@CaptSolo, eu tentei o seu exemplo, mas não funcionou.
Resultado:
Como você pode ver, existem dois o's e dois e's, mas eles entraram em grupos separados. Foi quando percebi que você precisava classificar a lista passada para a função groupby. Portanto, o uso correto seria:
Resultado:
Apenas lembrando, se a lista não estiver classificada, a função groupby não funcionará !
fonte
fonte
Você pode usar groupby para agrupar coisas para repetir. Você atribui ao grupo uma iterável e uma função- chave opcional / que pode ser chamada pela qual verificar os itens à medida que eles saem do iterável, e ele retorna um iterador que fornece duas tuplas do resultado da chave que pode ser chamada e dos itens reais em outro iterável. Da ajuda:
Aqui está um exemplo de groupby usando uma corotina para agrupar por uma contagem, ele usa uma chave que pode ser chamada (neste caso
coroutine.send
) para cuspir a contagem para quantas iterações e um sub-iterador agrupado de elementos:impressões
fonte
Um exemplo útil que me deparei pode ser útil:
Entrada de amostra: 14445221
Resultado da amostra: (1,1) (3,4) (1,5) (2,2) (1,1)
fonte
Essa implementação básica me ajudou a entender essa função. Espero que ajude outras pessoas também:
fonte
Você pode escrever a própria função groupby:
fonte