2012-06-20 7 views
7

Sto cercando un modo pulito per combinare le variabili in una singola stringa con un separatore predefinito. Il problema è che a volte alcune di queste variabili non esistono sempre o possono essere impostate su Nessuno. Non posso neanche duplicare la stringa del separatore. Esempio di problema:String join da Iterable contenente stringhe e (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---' 

C'è un bel modo pulito per fare questo?

+4

Meglio usare ' '-' join' invece di' str ('-') join' – jamylak

risposta

16

È possibile utilizzare una comprensione per popolare il proprio iterabile con un controllo condizionale che i valori abbiano un valore di verità.

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

preferisco questo alla mia risposta, perchè anche le maniglie stringhe vuote come vuole l'OP. –

+0

usa 'if item.strip()' per farlo funzionare anche con stringhe vuote. –

+0

Non è possibile utilizzare "if item.strip()" poiché fallirà su Nessuno o qualsiasi altro oggetto che non supporta strip() –

2

Se si desidera mantenere il numero di elementi costanti (ad esempio perché si vuole in uscita ad un foglio di calcolo in cui la lista è una riga e ogni elemento rappresenta una colonna), utilizzare:

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

BTW questo è anche il modo di andare se uno qualsiasi degli elementi che vuoi unire sono interi.

+0

Il modo in cui hai questo, inserisce il valore 'None' nella stringa come' 'chiave, tipo, frequenza, context_A, None, context_C''. Penso che molte persone vorrebbero utilizzare una stringa vuota. Per questo uso '','. Join (item o '' per item in your_list)' per ottenere ''chiave, tipo, frequenza, context_A ,, context_C''. Tuttavia, poiché ho dovuto eliminare il wrapper 'str()', non puoi usarlo per convertire interi. –

+0

questa è un'ottima soluzione se si verifica la convalida dell'input dove uno dei valori consentiti è Nessuno. –

1

È possibile utilizzare filter(bool, your_list) o filter(None, your_list) per rimuovere tutto ciò che restituisce False se convertito in bool, come False, Nessuno, 0, [],(), {}, "", forse altri.

È possibile utilizzare locals().get('mightnotexist') o globals().get('mightnotexist'), a seconda che la variabile sia locale o globale, per fare riferimento a una variabile che potrebbe non esistere. Questi restituiranno None se la variabile non esiste.

Il vostro codice potrebbe diventare:..

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

Preferisco questa soluzione perché è a mio parere più leggibile. –