2017-10-17 6 views
2

Ich arbeite an einem Nlp-Projekt, in dem ich Tags parsen muss. Ich habe mehrere Tags in der folgenden Form: eine Zeichenfolge, die eine Reihe von Tupel ist. Beispiel:Konvertiere einen Satz von Tupeln in Werte

'{(Entertainment (Adult), S), (Performing Arts, S), (Comedy Club, S), ($, S), (Comedy, P), (18+, S), (Plays & Shows, P)}' 

Aber ich will es so aussehen:

{('Entertainment (Adult)', 'S'), ('Performing Arts', 'S'), ('Comedy Club', 'S'), ('$', 'S'), ('Comedy', 'P'), ('18+', 'S'), ('Plays & Shows', 'P')} 

Ich versuchte literal_eval pro this question, aber ich erhalte einen ungültigen Syntaxfehler. Ich denke, das liegt daran, dass das Tag eine Menge ist, die Tupel enthält, die Strings enthalten, die nicht als Strings interpretiert werden, so dass das Literal_eval verwirrt wird (nur hier raten).

Ich habe versucht, einige Bandaid-Y-String-Streifen und Splits, aber ich kann keine Lösung, die dynamisch für verschiedene Tags funktioniert.

+0

Was ist, wenn die Tags Kommas und Klammern enthalten? Wäre es nicht einfacher, die Liste überhaupt erst richtig zu erstellen? –

+0

Tags werden immer in der gleichen Form sein: eine Menge von Tupeln, die zwei Werte enthalten. Ein anderes Beispiel wäre '{(All Ages, S), ($, S), (Alternative & Rock, S), (Konzerte & Live Musik, P)}' In []: – Daniel

+0

würde ich versuchen zuerst zu teilen Kommas und dann Paare verbinden. – Adirio

Antwort

2

können Sie reguläre Ausdrücke verwenden:

import re 
s = '{(Entertainment (Adult), S), (Performing Arts, S), (Comedy Club, S), ($, S), (Comedy, P), (18+, S), (Plays & Shows, P)}' 
final_data = [re.split(",\s+", i) for i in re.findall("\((.*?)\)", s)] 
final_data = [[re.sub("\(|\)", '', b) for b in i] for i in final_data] 
new_final_data = set(map(tuple, final_data)) 

Ausgang:

set([('Entertainment (Adult)', 'S'), ('Performing Arts', 'S'), ('Comedy Club', 'S'), ('$', 'S'), ('Comedy', 'P'), ('18+', 'S')]) 
+0

Das funktioniert, aber nichts für Strings mit einem einzigen Tag zurückgibt. Beispiel: "{(Concerts & Live Music, P)}" – Daniel

+0

@Daniel Versuchen Sie es erneut mit dem Code. – Ajax1234

1

Ich würde es auf diese Weise tun:

original = '{(Entertainment (Adult), S), (Performing Arts, S), (Comedy Club, S), ($, S), (Comedy, P), (18+, S), (Plays & Shows, P)}' 

splited = original[1:-1].split(',') 

splited = list(map(lambda x: x.strip(), splited)) 

grouped = [] 

for i in range(0, len(splited), 2): 
    grouped.append((splited[i][1:], splited[i+1][:-1])) 

print(grouped) 

Verwenden Sie die Variablennamen Sie bevorzugen. Ich benutze zuerst [1:-1], um die ersten und letzten Zeichen zu löschen ({ & }) und dann durch Kommas getrennt. Ich dann .strip() jeden Teil zum Löschen der ersten und letzten Leerzeichen. Zuletzt überspringe ich die Liste mit einem Schritt von 2 und lösche das erste Zeichen von ungeraden Elementen (() und das letzte Zeichen von geraden Elementen ()). Ich füge das resultierende Tupel in eine neue Liste ein.

Verwandte Themen