2012-06-20 20 views
7

Estoy buscando una manera limpia de combinar variables en una sola cadena con un separador predefinido. El problema es que a veces algunas de estas variables no siempre existen o pueden establecerse en Ninguna. Tampoco puedo duplicar la cadena separadora. Ejemplo de problema:Cadena Unir desde Iterable que contiene cadenas y (NoneType/Undefined)

# This works because I have all strings 
str('-').join(('productX', 'deployment-package', '1.2.3.4')) 
# 'productX-deployment-package-1.2.3.4' 

# But I have more args that might be None/or not exist like and that breaks 
str('-').join(('productX', 'deployment-package', '1.2.3.4', idontexist, alsonotexist)) 
str('-').join(('productX', 'deployment-package', '1.2.3.4', None, None, None)) 

# If I set the other missing variables to empty strings, I get duplicated joiners 
str('-').join(('productX', 'deployment-package', '1.2.3.4', '', '', '')) 
# 'productX-deployment-package-1.2.3.4---' 

¿Hay alguna manera limpia de hacer esto?

+4

mejor usar ' '-' en lugar de' join' str ('-') join' – jamylak

Respuesta

16

Puede usar una comprensión para completar su iterable con una comprobación condicional de que los valores tienen un valor verdadero.

your_list = ['productX', 'deployment-package', '1.2.3.4', None, None, None] 
'-'.join(item for item in your_list if item) 
+1

prefiero esto a mi propia respuesta, porque también las manijas cadenas vacías como el OP quiere. –

+0

usa 'if item.strip()' para que funcione también con cadenas vacías. –

+0

No puede usar "if item.strip()" porque fallará en None o en cualquier otro objeto que no admita strip() –

2

Si desea mantener constante el número de elementos (por ejemplo, porque desea dar salida a una hoja de cálculo en la lista es una fila y cada elemento representa una columna), utilice:

your_list = ['key', 'type', 'frequency', 'context_A', None, 'context_C'] 
'\t'.join(str(item) for item in your_list) 

Por cierto, este es también el camino a seguir si alguno de los elementos que desea unir son enteros.

+0

La forma en que tienes esto, pone el valor 'None' en la cadena como' 'key, type, frequency, context_A, None, context_C''. Creo que la mayoría de la gente querría que se usara una cadena vacía. Para eso uso '','. Join (item o '' para item en tu_list)' para obtener ''key, type, frequency, context_A ,, context_C''. Sin embargo, debido a que tuve que soltar el contenedor 'str()', no puede usarlo para convertir enteros. –

+0

esta es una gran solución si está validando una entrada donde uno de los valores permitidos es Ninguno. –

1

Puede usar filter(bool, your_list) o filter(None, your_list) para eliminar todo lo que se evalúa como False cuando se convierte a bool, como False, None, 0, [],(), {}, '', tal vez otros.

Puede usar locals().get('mightnotexist') o globals().get('mightnotexist'), dependiendo de si la variable se espera sea local o global, para hacer referencia a una variable que podría no existir. Estos devolverán None si la variable no existe.

Su código podría llegar a ser:..

items = ('productX', 
     'deployment-package', 
     '1.2.3.4', 
     locals().get('idontexist'), 
     globals().get('alsonotexist'), 
     None, 
     None, 
     '') 
'-'.join(filter(bool, items)) 
+0

Prefiero esta solución porque está en mi opinión más legible. –

Cuestiones relacionadas