2011-06-25 15 views
8

O esto es un error, o que voy a aprender algo nuevo acerca de cómo se comporta Python. :)Bug en la función(), str.rstrip de Python o de mi propia estupidez?

tengo un diccionario lleno de pares clave/valor. Cada tecla tiene un prefijo único, ias_XX_XX_. Estoy intentando obtener una lista de cada prefijo único en el diccionario.

  1. En primer lugar me da una lista de todas las claves que terminan en '_x1'.
  2. A continuación, tira '_x1' de todos ellos utilizando rstrip('_x1').

Esto funciona bien para todos ellos, a excepción de la última, ias_1_1_x1. En lugar de ser despojado de ias_1_1, se convierte en ias_. Ejecutar el código para ver por sí mismo:

d = { 
'ias_16_10_x2':  575, 
'ias_16_10_x1':  0, 
'ias_16_10_y1':  0, 
'ias_16_10_y2':  359, 
'ias_16_9_x2':  575, 
'ias_16_9_x1':  0, 
'ias_16_9_y1':  18, 
'ias_16_9_y2':  341, 
'ias_1_1_y1':  0, 
'ias_1_1_y2':  359, 
'ias_1_1_x2':  467, 
'ias_1_1_x1':  108, 
} 

x1_key_matches = [key for key in d if '_x1' in key] 
print x1_key_matches 

unique_ids = [] 
for x1_field in x1_key_matches: 
    unique_ids.append(x1_field.rstrip('_x1')) 

print unique_ids 

Salida Real: (Python 2.6, 2.7 y 3.2 (debe cambiar de impresión para imprimir() para 3.x para trabajar))

['ias_16_10_x1', 'ias_16_9_x1', 'ias_1_1_x1'] 
['ias_16_10', 'ias_16_9', 'ias'] # <<<--- Why isn't this last one ias_1_1??? 

Resultados esperados:

['ias_16_10_x1', 'ias_16_9_x1', 'ias_1_1_x1'] 
['ias_16_10', 'ias_16_9', 'ias_1_1'] 

Si cambio el nombre de la clave de ias_1_1 a algo así como ias_1_2, o ias_1_3, el fallo no ocurre. ¿Por qué está pasando esto?

+0

En retrospectiva, podría haber sido más correcta y menos confuso si el argumento de 'rstrip' se establece un lugar de una lista. Pero los conjuntos se agregaron más tarde a Python. –

+2

Siempre puede cortar los últimos tres caracteres: 'uids = [tecla [: - 3] para la tecla d si key.endswith (" _ x1 ")]'. Tenga en cuenta que 'endswith' no es lo mismo que la prueba que ha ejecutado. – katrielalex

Respuesta

20

El parámetro a rstrip() es un conjunto de caracteres a ser despojado, no una cadena exacta:

>>> "abcbcbaba".rstrip("ab") 
"abcbc" 

sugerencia general: Si sospecha que hay un error en alguna función, leer su documentation.

+6

¡Ah, ja! RTFM para mí :) –

+0

nunca se dio cuenta de esto! por el nombre era fácil malinterpretar como eliminar la 'cosa' al final .. – kollery

5

Desde el docs, énfasis añadido:

El argumento caracteres es una cadena que especifica el conjunto de caracteres que se puede quitar. Si se omite o None, el argumento chars se predetermina a eliminar espacios en blanco. El argumento de caracteres no es un sufijo; más bien, todas las combinaciones de sus valores se eliminan.

4

. El parámetro .rstrip no es la cadena que queremos quitar, son los caracteres que queremos quitar. Compruebe que los ejemplos:

>>> "12345678".rstrip("158") 
'1234567' 
>>> "12345678".rstrip("asd8qwe") 
'1234567' 
>>> "12345678".rstrip("78") 
'123456' 
>>> "1234568788".rstrip("78") 
'123456' 
2

probar esto en su lugar:

unique_ids.append(re.sub('_x1$', '', x1_field) 
+3

Gracias. Terminé usando 'unique_ids.append (x1_field.rsplit ('_ x1', 1) [0])'. ¿Tiene algún beneficio con el uso de su solución de expresiones regulares? –

+0

No realmente. Optimización prematura tal vez? :) Pero no sé cuál es el más rápido. –

+3

Pero debo admitir que me gusta más su solución ... y en base a algunas pruebas muy rápidas, parece ser al menos dos veces más rápido que la primera. Nota para uno mismo: deja de confiar en expresiones regulares para todo. –

0

rstrip devuelve una copia de la cadena con caracteres finales retirados.

Por ejemplo:

>>> ' spacious '.rstrip() 
' spacious' 
>>> "AABAA".rstrip("A") 
'AAB' 
>>> "ABBA".rstrip("AB") # both AB and BA are stripped 
'' 
>>> "ABCABBA".rstrip("AB") 
'ABC' 

######## 

>>> ' spacious '.rstrip() 
' spacious' 
>>> 'mississippi'.rstrip('ipz') 
'mississ' 

Si se trata de nombres de archivo ser muy cuidadoso,

>>> "cosmac.csv".replace(".csv") 
'cosma' 
>>> "cosmac.csv".replace(".csv", "") 
'cosmac' 

Espero que esto ayude!

Cuestiones relacionadas