2012-06-20 5 views
7

Ich bin auf der Suche nach einer sauberen Möglichkeit, Variablen in einer einzigen Zeichenfolge mit einem vordefinierten Trennzeichen zu kombinieren. Das Problem ist, dass manchmal einige dieser Variablen nicht immer existieren oder auf None gesetzt werden können. Ich kann die Trennzeichenfolge auch nicht duplizieren. Beispiel für ein Problem:String Join von Iterable mit Strings und (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---' 

Gibt es eine schöne, saubere Möglichkeit, dies zu tun?

+4

besser zu nutzen ' '-' join' statt' str ('-') join' – jamylak

Antwort

16

Sie können ein Verständnis verwenden, um Ihr iterables mit einer bedingten Überprüfung zu füllen, dass Werte einen truthy Wert haben.

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

ich das lieber meine eigene Antwort, weil es Griffe auch Leerstrings wie das OP will. –

+0

Verwenden Sie 'if item.strip()', damit es auch mit leeren Strings funktioniert. –

+0

Sie können "if item.strip()" nicht verwenden, da es fehlschlägt. Keines oder ein anderes Objekt, das strip() nicht unterstützt. –

2

Wenn Sie die Anzahl der Elemente konstant halten wollen (zum Beispiel, weil Sie in eine Tabelle ausgegeben werden sollen, wo die Liste eine Zeile und jedes Element stellt eine Spalte) verwenden:

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

BTW dies ist auch der Weg zu gehen, wenn alle Elemente, die Sie beitreten wollen, ganze Zahlen sind.

+0

Die Art, wie Sie das haben, setzt den Wert 'None' in die Zeichenfolge wie' 'key, type, frequency, context_A, None, context_C''. Ich denke, die meisten Leute würden gerne eine leere Saite benutzen. Dafür verwende ich '',' join (Element oder '' für Element in Ihrer_Liste) ', um' 'Schlüssel, Typ, Häufigkeit, Kontext_A ,, Kontext_C'' zu erhalten. Da ich jedoch den Wrapper 'str()' löschen musste, können Sie ihn nicht zum Konvertieren von Ganzzahlen verwenden. –

+0

Dies ist eine großartige Lösung, wenn Sie eine Eingabe validieren, bei der einer der zulässigen Werte None ist. –

1

Sie können filter(bool, your_list) oder filter(None, your_list) verwenden, um alles zu entfernen, das zu False ausgewertet wird, wenn es in ein Bool konvertiert wird, z. B. False, None, 0, [],(), {}, '' möglicherweise auch andere.

Sie können locals().get('mightnotexist') oder globals().get('mightnotexist') verwenden, abhängig davon, ob die Variable lokal oder global sein soll, um auf eine Variable zu verweisen, die möglicherweise nicht existiert. Diese geben None zurück, wenn die Variable nicht existiert.

Code könnte geworden:..

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

Ich bevorzuge diese Lösung, weil sie meiner Meinung nach besser lesbar ist. –