¿Existe una manera pitónica de cortar un tipo de secuencia de tal manera que el corte devuelto sea de longitud aleatoria y en orden aleatorio ? Por ejemplo, algo como:

>>> l=["a","b","c","d","e"]
>>> rs=l[*:*]
>>> rs
['e','c']
6
AJ. 29 may. 2011 a las 20:07

3 respuestas

La mejor respuesta

Qué tal si...

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

Puede encontrar un enlace rápido a documentos para el módulo aleatorio aquí.

13
Andrew White 29 may. 2011 a las 16:12

No tengo lenguaje que yo sepa, pero random.sample hace lo que necesitas.

>>> 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]
4
Simon Whitaker 29 may. 2011 a las 16:19

Hay una sutil distinción que ni su pregunta ni las otras respuestas abordan, así que creo que debería señalarlo. Se ilustra con el siguiente ejemplo.

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

Como puede ver en la salida, la primera versión no "divide" la lista, sino que solo la muestra, por lo que los valores de retorno pueden ser de cualquier parte de la lista. Si literalmente desea un "segmento" de la lista, es decir, si desea restringir el espacio muestral antes del muestreo, entonces lo siguiente no hace lo que desea:

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

En cambio, tendrías que hacer algo como esto:

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

Pero creo que una forma aún mejor de hacerlo sería así:

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

Lamentablemente, no conozco ninguna versión de devolución de copias de shuffle (es decir, una shuffled similar a sorted).

4
senderle 29 may. 2011 a las 17:38