Qual é a melhor maneira de dividir uma lista em partes aproximadamente iguais? Por exemplo, se a lista possui 7 elementos e é dividida em 2 partes, queremos obter 3 elementos em uma parte e a outra deve ter 4 elementos.
Estou procurando por algo assim se even_split(L, n)
divide L
em n
partes.
def chunks(L, n):
""" Yield successive n-sized chunks from L.
"""
for i in range(0, len(L), n):
yield L[i:i+n]
O código acima fornece pedaços de 3, em vez de 3. Eu poderia simplesmente transpor (iterar sobre isso e pegar o primeiro elemento de cada coluna, chamar essa parte um, depois pegar o segundo e colocá-lo na parte dois, etc.), mas isso destrói a ordem dos itens.
>>> chunkIt(range(8), 6)
=>[[0], [1], [2, 3], [4], [5], [6], [7]]
chunkIt(range(10), 9)
deve retornar 9 partes, mas não.Você pode escrevê-lo simplesmente como um gerador de lista:
Exemplo:
fonte
n = min(n, len(a)) # don't create empty buckets
na linha 1 para evitar a criação de baldes vazios em cenários comolist(split(range(X, Y)))
ondeX < Y
Esta é a razão de ser de
numpy.array_split
*:* crédito para Zero Pireu no quarto 6
fonte
*
noprint
para?print(L)
e `imprima (* L). Consulte também stackoverflow.com/a/36908/2184122 ou procure por "uso de asterisco em python".Contanto que você não queira nada bobo como pedaços contínuos:
fonte
zip(*chunkify(range(13), 3))
resultados em[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11)]
Alterando o código para gerar
n
pedaços em vez de pedaços den
:que dá:
Isso atribuirá os elementos extras ao grupo final, o que não é perfeito, mas está dentro da especificação de "aproximadamente N partes iguais" :-) Com isso, quero dizer que 56 elementos seriam melhores que (19,19,18), enquanto isso fornece (18,18,20).
Você pode obter uma saída mais equilibrada com o seguinte código:
quais saídas:
fonte
for x in chunks(mylist,num): print x
obtenho os pedaços desejados, mas entre eles recebo uma lista vazia. Alguma idéia do porquê? Ou seja, recebo muito[]
, um após cada pedaço.Se você dividir
n
elementos emk
partes aproximadas, poderá torná-n % k
las 1 elemento maiores que as outras partes para distribuir os elementos extras.O código a seguir fornecerá o comprimento dos pedaços:
Exemplo:
n=11, k=3
resulta em[4, 4, 3]
Você pode calcular facilmente os índices de início dos blocos:
Exemplo:
n=11, k=3
resulta em[0, 4, 8]
Usando o
i+1
th chunk como limite, obtemos que oi
th chunk da listal
com lenn
éComo etapa final, crie uma lista de todos os pedaços usando a compreensão da lista:
Exemplo:
n=11, k=3, l=range(n)
resulta em[range(0, 4), range(4, 8), range(8, 11)]
fonte
Isso fará a divisão por uma única expressão:
A lista neste exemplo tem o tamanho 18 e é dividida em 5 partes. O tamanho das peças não difere em mais de um elemento.
fonte
Veja
more_itertools.divide
:Instale via
> pip install more_itertools
.fonte
Aqui está um que é adicionado
None
para tornar as listas iguais em tamanhofonte
Aqui está a minha solução:
Produz
fonte
Aqui está um gerador que pode lidar com qualquer número positivo (inteiro) de chunks. Se o número de blocos for maior que o comprimento da lista de entrada, alguns blocos estarão vazios. Esse algoritmo alterna entre pedaços curtos e longos, em vez de segregá-los.
Eu também incluí algum código para testar a
ragged_chunks
função.Podemos tornar isso um pouco mais eficiente exportando a multiplicação para a
range
chamada, mas acho que a versão anterior é mais legível (e DRYer).fonte
Dê uma olhada no numpy.split :
fonte
Implementação usando o método numpy.linspace.
Basta especificar o número de partes em que você deseja dividir a matriz. As divisões terão tamanho quase igual.
Exemplo:
Dá:
fonte
Minha solução, fácil de entender
E o menor verso desta página (escrito por minha garota)
fonte
Usando a compreensão da lista:
fonte
Outra maneira seria algo assim, a idéia aqui é usar garoupa, mas se livrar
None
. Nesse caso, todos os 'small_parts' serão formados a partir de elementos na primeira parte da lista e 'large_parts' da parte posterior da lista. O comprimento das 'partes maiores' é len (small_parts) + 1. Precisamos considerar x como duas sub-partes diferentes.A maneira como eu o configurei retorna uma lista de tuplas:
fonte
Aqui está outra variante que espalha os elementos "restantes" uniformemente entre todos os blocos, um de cada vez, até que não haja mais nenhum. Nesta implementação, os blocos maiores ocorrem no início do processo.
Por exemplo, gere 4 pedaços de uma lista de 14 elementos:
fonte
O mesmo que a resposta do trabalho , mas leva em consideração listas com tamanho menor que o número de pedaços.
se n (número de blocos) for 7 e lst (a lista a ser dividida) for [1, 2, 3], os blocos serão [[0], [1], [2]] em vez de [[0], [1 ], [2], [], [], [], []]
fonte
Você também pode usar:
fonte
Exemplo:
l = [a for a in range(97)]
deve ser composto por 10 partes, cada uma com 9 elementos, exceto o último.Resultado:
fonte
Digamos que você queira dividir uma lista [1, 2, 3, 4, 5, 6, 7, 8] em 3 listas de elementos
como [[1,2,3], [4, 5, 6], [7, 8]] , onde se os últimos elementos restantes restantes forem menores que 3, eles serão agrupados.
Saída: [[1,2,3], [4, 5, 6], [7, 8]]
Onde o comprimento de uma peça é 3. Substitua 3 pelo seu próprio tamanho de pedaço.
fonte
1>
2>
fonte
aqui está a minha versão (inspirada no Max's)
fonte
Arredondar o espaço lins e usá-lo como um índice é uma solução mais fácil do que o proposto pelo amit12690.
fonte
Escolhido a partir deste link , e foi isso que me ajudou. Eu tinha uma lista predefinida.
fonte
digamos que você deseja dividir em 5 partes:
fonte
Escrevi código neste caso:
divide_ports (1, 10, 9) retornaria
fonte
este código funciona para mim (compatível com Python3):
exemplo (para o tipo bytearray , mas também funciona para as listas s):
fonte
Este fornece pedaços de comprimento <= n,> = 0
def
por exemplo
fonte
Tentei a maior parte das soluções, mas elas não funcionaram para o meu caso, por isso crio uma nova função que funciona na maioria dos casos e em qualquer tipo de matriz:
fonte