2011-12-01 20 views
6

quiero asignar al azar el caso de una cadena, aquí está lo que tengo:pitones manera más rápida de aleatorización caso de una cadena

word="This is a MixeD cAse stRing" 
word_cap='' 
for x in word: 
     if random.randint(0,1): 
       word_cap += x.upper() 
     else: 
       word_cap += x.lower() 
     word = word_cap 

print word 

Im preguntándose si podría utilizar comprensión de lista para hacerlo más rápido. no pude parecen utilizar las funciones inferior() y superior() en randomchoice Traté de hacer algo como

''.join(randomchoice(x.upper(),x.lower()) for x in word) 

pero creo que eso es incorrecto. algo así, aunque es posible?

Respuesta

8
import random 
s = 'this is a lower case string' 

''.join(random.choice((str.upper,str.lower))(x) for x in s) 

random.choice selecciona aleatoriamente uno de dos funciones str.upper, str.lower.

Luego esta función se aplica a x para cada letra en la cadena de entrada s.

Si cadena inicial tiene todas las letras en minúsculas, que iba a utilizar este código:

''.join(x.upper() if random.randint(0,1) else x for x in s) 

debido a que el código inicial utilizaría redundante str.lowercase en medio de las letras en el caso de cadena inicial minúscula.

Por cierto, mira la otra respuesta de Michael J. Barber. Python tiene fuertes cargos por llamadas a funciones. En su código él llama al str.upper solo una vez. En mi código str.upper se usa la mitad de los símbolos de la cadena inicial. Por lo tanto, aún se crea una cadena de mayúsculas temporal en la memoria, la eficiencia de tiempo de su código puede ser mucho mayor.


hete aquí:

Código comparaciones de tiempo: https://ideone.com/eLygn

+2

Por qué lo llaman 'str.lower()' en una cadena que ya está en minúsculas? –

+0

podría ser en cualquier caso. ¡gracias chicos! –

+1

@TimPietzcker porque la cadena inicial puede tener letras en mayúscula – ovgolovin

4

Prueba esto:

word="this is a lower case string" 
caps = word.upper() 
''.join(x[random.randint(0,1)] for x in zip(word, caps)) 

Esto debe superar a su versión, ya que hace muchas menos llamadas a upper y porque, lo que es más importante, evita el agregado de O (N^2) que utilizó en la versión con los bucles.

Con la modificación a la pregunta, que necesita para crear la versión en minúsculas y mayúsculas:

word="This is a MixeD cAse stRing" 
caps = word.upper() 
lowers = word.lower() 
''.join(random.choice(x) for x in zip(caps, lowers)) 

Según lo sugerido por Tim Pietzcker en los comentarios, que he usado random.choice para seleccionar las cartas de las tuplas creadas por la llamada zip.

Dado que la pregunta ha sido cambiado para centrarse más en la velocidad, el enfoque más rápido es probable que se utiliza Numpy:

''.join(numpy.where(numpy.random.randint(2, size=len(caps)), list(caps), list(lowers))) 
+3

+1, pero 'random.choice (x) para x en zip (...)' se vería más bonito IMO. –

+0

yeh no mencioné el caso mixto, lo siento. esto se ve más rápido, gracias. actualicé mi pregunta –

+0

Agregué comparaciones de tiempo a la respuesta. @TimPietzcker – ovgolovin

Cuestiones relacionadas