2011-05-29 19 views
6

¿Hay una manera pitónica de dividir un tipo de secuencia tal que el segmento devuelto sea de longitud aleatoria y en orden aleatoria? Por ejemplo, algo como:Python Random Slice Idiom

>>> l=["a","b","c","d","e"] 
>>> rs=l[*:*] 
>>> rs 
['e','c'] 

Respuesta

13

¿Qué tal ...

random.sample(l, random.randint(1, len(l))) 

enlace rápido a documentos para el módulo al azar se puede encontrar here.

4

No hay idioma que yo sepa, pero random.sample hace lo que necesita.

>>> from random import sample, randint 
>>> 
>>> def random_sample(seq): 
...  return sample(seq, randint(0, len(seq))) 
... 
>>> a = range(0,10) 
>>> random_sample(a) 
[] 
>>> random_sample(a) 
[4, 3, 9, 6, 7, 1, 0] 
>>> random_sample(a) 
[2, 8, 0, 4, 3, 6, 9, 1, 5, 7] 
+2

¿Por qué votar abajo? –

4

Hay una distinción sutil que ni su pregunta ni las otras respuestas abordan, así que creo que debo señalarlo. Está ilustrado por el ejemplo a continuación.

>>> random.sample(range(10), 5) 
[9, 2, 3, 6, 4] 
>>> random.sample(range(10)[:5], 5) 
[1, 2, 3, 4, 0] 

Como se puede ver en la salida, la primera versión no "cortar" la lista, pero sólo las muestras de TI, por lo que los valores de retorno puede ser de cualquier lugar en la lista. Si quieres, literalmente, una "rebanada" de la lista - es decir, si desea limitar el espacio de muestra antes del muestreo - a continuación, la siguiente no hace lo que quiere:

random.sample(l, random.randint(1, len(l))) 

En su lugar, se tengo que hacer algo como esto:

sample_len = random.randint(1, len(l)) 
random.sample(l[:sample_len], sample_len) 

Pero creo que una mejor manera de hacer esto sería así:

shuffled = l[:random.randint(1, len(l))] 
random.shuffle(shuffled) 

Desafortunadamente no hay ninguna versión de copia de regresar de shuffle que yo Estoy al tanto de (es decir a shuffled similar a sorted).

+0

+1 para obtener información sobre el comentario "rebanada" literal y la solución propuesta. –

+0

@senderle '' shuffled = lambda p: sample (p, len (p)) '' –