2016-09-01 3 views
6

Ich versuche, eine Liste von Strings in eine Liste von Tupeln ungleicher Länge aufzuteilen, die diese Strings enthalten, wobei jedes Tupel Strings enthält, die anfänglich durch leere Strings getrennt sind. Im Grunde würde ich die parametrisierte Aufteilung benötigen, die ich auf Listen anwenden könnte. Wenn meine erste Liste wie folgt aussieht:Aufteilen einer Liste in ungleichmäßige Tupel

init = ['a', 'b', '', 'c', 'd e', 'fgh', '', 'ij', '', '', 'k', 'l', ''] 

Das letzte Element dieser Liste ist immer eine Schließung ''. Es kann aufeinanderfolgende '' s geben, die als Singles gelten. Das Ergebnis was ich brauche ist:

end = [('a', 'b'), ('c', 'd e', 'fgh'), ('ij',), ('k', 'l')] 

ich schon hässlich Code haben, der die Arbeit erledigt und wird außerhalb der Reichweite, wenn die Liste vollständig aufgetaucht ist out:

end = [] 
while init[-1] == u'': 
init.pop() 
l = [] 
while init[-1] != u'': 
    l.append(init.pop()) 
end.append(tuple(l)) 

Ich möchte Comprehensions verwenden , aber nachdem ich erfolglos versucht habe, die Argumentlisten zu entpacken, selbstreferenzierte Listen umzukehren, deque Warteschlangen und verschiedene Code-Gerüche zu verwenden, zweifle ich jetzt daran, ob es sinnvoll ist, nach einer (verschachtelten) Verständnislösung zu suchen.

Antwort

4

können Sie itertools.groupby Funktion Gruppe verwenden, um die auf ihren Größen basierende Elemente, wie diese

>>> from itertools import groupby 
>>> init = ['a', 'b', '', 'c', 'd e', 'fgh', '', 'ij', '', '', 'k', 'l', ''] 
>>> [tuple(g) for valid, g in groupby(init, key=lambda x: len(x) != 0) if valid] 
[('a', 'b'), ('c', 'd e', 'fgh'), ('ij',), ('k', 'l')] 

die Elemente dieses im Allgemeinen Gruppen auf der Grundlage ihrer Längen. Wenn die Länge des Elements ungleich Null ist, werden sie in eine Gruppe eingefügt, bis ein Element aus einer anderen Gruppe erfüllt ist. Die key Funktion würde True für die Gruppe von Elementen zurückgeben, deren Länge nicht gleich Null ist, andernfalls False. Wir ignorieren die Gruppe mit False (daher die Prüfung if valid).

+1

Ist es schön, die Lambda-Funktion mit 'bool' ersetzen die Zeichenfolge zu werfen und ein ähnliches Ergebnis erhalten? – Felix

4

Hier ist ein kurzer und allgemeiner Ansatz mit groupby wenn Sie Ihre Liste mit einem speziellen Trennzeichen teilen mögen:

>>> delimiter = '' 
>>> [tuple(g) for k, g in groupby(init, delimiter.__eq__) if not k] 
[('a', 'b'), ('c', 'd e', 'fgh'), ('ij',), ('k', 'l')] 
Verwandte Themen