2010-11-07 12 views
11

Duplicar posibles:
How do you split a list into evenly sized chunks in Python?cómo dividir una lista en n partes iguales, pitón

Dada (cualquier) lista de palabras lst debería dividirlo en 10 partes iguales .

x = len(lst)/10 

cómo dar a estas partes nombres variables?

En la salida necesito 10 variables (part1, part2... part10) con x cantidad de palabras en ella.

¿Alguna idea?

+1

Usted no da los nombres de las piezas. Usted devuelve una lista de listas. – delnan

+0

¿Cómo dividir? '[1,2,3,4,5, ... 100]' se convierte en '[1,2,3, ...], [11,12,13, ...], ...' o ' [1,11,21, ...], [2,12,22, ...], ... 'o al azar o qué? – kennytm

+0

¿Por qué no una tupla u otra lista, que contendrá las sublistas? ¿Y luego recomendar usar la posición? Sería más dinámico que usar variables.

 res = divide_list(l, 10) print res[0] 
khachik

Respuesta

2

Consulte this question para saber cómo generar partes iguales de una lista. Entonces, si realmente los necesita en las variables independientes, puede hacer:

part1, part2, ..., part10 = (part for part in chunks(lst, len(lst)/10)) 

Pero yo recomendaría hacer el código más general, en lugar de codificar a 10 partes.

1

Escribiré este código para que aprenda la técnica, pero no debe hacer esto. El punto de los tipos de datos de contenedor como list y set es que puede tener contenidos arbitrarios sin tener que hacer variables para cada elemento. Así,

No hagas esto

>>> def chunks(l, n): 
...  for i in xrange(0, len(l), n): 
...   yield l[i:i+n] 
... 
>>> for i, chunk in enumerate(chunks(range(100), 10)): 
...  locals()["part{0}".format(i)] = chunk 
... 
>>> part0 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
>>> part1 
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19] 
>>> part2 
[20, 21, 22, 23, 24, 25, 26, 27, 28, 29] 

(La receta es de chunksNed Batchelder's answer en la cuestión vinculada. La razón por la que no debe hacer esto es que la modificación de locals (o, de hecho globals o vars) es no buenas prácticas: causa y difíciles de determinar el comportamiento de los insectos y posiblemente muy desagradables

+1

'trozos' no divide l en n partes, divide l en' len (l)/n + 1' partes si 'len (l)% n! = 0' o' len (l)/n' partes si 'len (l)% n == 0'. – khachik

28

de una sola línea el retorno de una lista de listas, dada una lista y el tamaño del fragmento:.

>>> lol = lambda lst, sz: [lst[i:i+sz] for i in range(0, len(lst), sz)] 

Pruebas:

>>> x = range(20, 36) 
>>> print x 
[20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35] 

>>> lol(x, 4) 
[[20, 21, 22, 23], 
[24, 25, 26, 27], 
[28, 29, 30, 31], 
[32, 33, 34, 35]] 

>>> lol(x, 7) 
[[20, 21, 22, 23, 24, 25, 26], 
[27, 28, 29, 30, 31, 32, 33], 
[34, 35]] 

Actualización:

Creo que la pregunta está pidiendo realmente es una función que, dada una lista y un número, devuelve una lista que contiene $ (número) listas, con los artículos de la lista original distribuidos uniformemente. Entonces tu ejemplo de lol (x, 7) realmente debería devolver [[20,21,22], [23,24,25], [26,27], [28,29], [30,31], [32] , 33], [34,35]]. - markrian

Pues bien, en este caso, se puede tratar:

def slice_list(input, size): 
    input_size = len(input) 
    slice_size = input_size/size 
    remain = input_size % size 
    result = [] 
    iterator = iter(input) 
    for i in range(size): 
     result.append([]) 
     for j in range(slice_size): 
      result[i].append(iterator.next()) 
     if remain: 
      result[i].append(iterator.next()) 
      remain -= 1 
    return result 

Estoy seguro que esto se puede mejorar, pero me siento perezoso.:-)

>>> slice_list(x, 7) 
[[20, 21, 22], [23, 24, 25], 
[26, 27], [28, 29], 
[30, 31], [32, 33], 
[34, 35]] 
+1

Creo que la pregunta realmente es pedir una función que, dada una lista y un número, devuelve una lista que contiene $ (número) listas, con los elementos de la lista original distribuidos uniformemente. – markrian

+0

Así que su ejemplo de lol (x, 7) realmente debería devolver [[20,21,22], [23,24,25], [26,27], [28,29], [30,31], [ 32,33], [34,35]]. – markrian

+0

@markrian: tenga en cuenta que muchas personas entendieron mal la pregunta, que es un indicador de su calidad, pero puede estar en lo cierto, consulte mi actualización. –

0

Uso tupla/lista de resultado - el enfoque más razonable

Si es necesario definir nuevas variables, puede

  1. uso setattr y añadir nuevos atributos a cualquier object . Es seguro ya que no sobrescribir las variables existentes:.
     
    res = object() 
    ... 
    setattr(res, "part"+index, part_generated) 
    
  2. complemento genera variables para locals()globals() o diccionario en función del contexto de su código se ejecuta en
0

varias soluciones visto, pero no pudo evitar mina de mensaje:

# List 
lst = range(103) 

# number of slices 
nSlices = 10 

# splitted list 
slices = [len(lst) // (nSlices)] * nSlices 

# but points are still missing! 
remainder = len(lst)-sum(slices) 

# split missing points across slices 
slices[:remainder] = [ii + 1 for ii in slices[:remainder]] 

splittedList = [lst[sum(slices[:ii]):sum(slices[:ii+1])] for ii in    range(nSlices)] 
print lst 
print '\n'.join("{}".format(n) for n in splittedList) 

probablemente se puede resumir aún más, por supuesto, pero creo que de esta manera es claro para leer.

1

Si no es necesario para hacer cumplir piezas contiguas de elementos de salida, entonces el siguiente fragmento sencilla hará el trabajo:

def even_divide(lst, num_piece=4): 
    return [ 
     [lst[i] for i in range(len(lst)) if (i % num_piece) == r] 
     for r in range(num_piece) 
    ] 

elementos Básicamente el código es la agrupación en base a residuos de módulo. Y precisamente por eso, los elementos en la lista de salida no serán contiguos. Por ejemplo, si la entrada es range(21), en lugar de

[[0, 1, 2, 3, 4, 5],[6, 7, 8, 9, 10],[11, 12, 13, 14, 15],[16, 17, 18, 19, 20]] 

se obtendría

[[0, 4, 8, 12, 16, 20],[1, 5, 9, 13, 17],[2, 6, 10, 14, 18],[3, 7, 11, 15, 19]] 

espero que ayude.

0

Para lograr el mismo resultado que la actualización de Paulo (divida una lista en n trozos con un tamaño que solo difiera en 1), la siguiente es una solución elegante que utiliza recursividad.

def divide(lst, n): 
    p = len(lst) // n 
    if len(lst)-p > 0: 
     return [lst[:p]] + divide(lst[p:], n-1) 
    else: 
     return [lst] 

Ejemplo:

lst = list(range(13)) 
print divide(lst,5) # [[0, 1], [2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]] 
Cuestiones relacionadas