2016-02-21 9 views
7

Ich habe diese Liste erstellt; jedes Element ist eine Zeichenfolge, die Kommas (in einigen Fällen) und Colon (immer) enthält:Verwenden von Python-Funktionen höherer Ordnung zum Bearbeiten von Listen

dinner = [ 
    'cake,peas,cheese : No', 
    'duck,broccoli,onions : Maybe', 
    'motor oil : Definitely Not', 
    'pizza : Damn Right', 
    'ice cream : Maybe', 
    'bologna : No', 
    'potatoes,bacon,carrots,water: Yes', 
    'rats,hats : Definitely Not', 
    'seltzer : Yes', 
    'sleeping,whining,spitting : No Way', 
    'marmalade : No' 
] 

Ich möchte erstellen Sie eine neue Liste von dem oben wie folgt:

['cake : No', 
'peas : No', 
'cheese : No', 
'duck : Maybe', 
'broccoli : Maybe', 
'onions : Maybe', 
'motor oil : Definitely Not', 
'pizza : Damn Right', 
'ice cream : Maybe', 
'bologna : No', 
'potatoes : Yes', 
'bacon : Yes', 
'carrots : Yes', 
'water : Yes', 
'rats : Definitely Not', 
'hats : Definitely Not', 
'seltzer : Yes', 
'sleeping : No Way', 
'whining : No Way', 
'spitting : No Way', 
'marmalade : No'] 

Aber ich Ich würde gerne wissen, ob/wie es möglich ist, dies in einer oder zwei Zeilen mit effizientem Code zu tun, der hauptsächlich die Funktionen höherer Ordnung von Python verwendet. Ich habe es versucht:

reduce(lambda x,y: x + y, (map(lambda x: x.split(':')[0].strip().split(','), dinner)))

... produziert diese:

['cake', 
'peas', 
'cheese', 
'duck', 
'broccoli', 
'onions', 
'motor oil', 
'pizza', 
'ice cream', 
'bologna', 
'potatoes', 
'bacon', 
'carrots', 
'water', 
'rats', 
'hats', 
'seltzer', 
'sleeping', 
'whining', 
'spitting', 
'marmalade'] 

... aber ich bin zu kämpfen mit dem Stück jeder Zeichenfolge anhängt nach dem Doppelpunkt auf jedem zurück Artikel.

+0

Warum sind Sie besorgt über die Codelänge? Dies wäre auf lange Sicht viel weniger haltbar. – jpmc26

+0

@ jpmc26 Ich verstehe, woher du kommst und stimmst zu. Dies ist für mich eher eine explorative Übung, um die Fähigkeiten von Pythons hofs zu verstehen. – dstar

Antwort

3

Angenommen, Sie müssen es als eine Liste von Strings wirklich im Vergleich zu einem Wörterbuch , die wie eine bessere Datenstruktur aussieht.

Durch vereinfachen Comprehensions verwenden, können Sie dies tun:

>>> [[x+':'+y for x in i.split(',')] 
... for i, y in map(lambda l: map(str.strip, l.split(':')), dinner)] 
[['cake:No', 'peas:No', 'cheese:No'], 
['duck:Maybe', 'broccoli:Maybe', 'onions:Maybe'], 
['motor oil:Definitely Not'], 
... 
['marmalade:No']] 

Jetzt nur add auf den Listen:

>>> from operator import add 
>>> reduce(add, ([x+':'+y for x in i.split(',')] 
...    for i, y in map(lambda l: map(str.strip, l.split(':')), dinner)), []) 
['cake:No', 
'peas:No', 
'cheese:No', 
'duck:Maybe', 
... 
'marmalade:No'] 

Oder abflachen nur die Liste:

>>> [a for i, y in map(lambda l: map(str.strip, l.split(':')), dinner) 
... for a in (x+':'+y for x in i.split(','))] 
['cake:No', 
'peas:No', 
'cheese:No', 
'duck:Maybe', 
... 
'marmalade:No'] 
+0

'flatten' ist eingebaut als' itertools.chain.from_iterable' – Caridorc

+0

@AChampion danke. Einige Leute haben großartigen Code gepostet, der gut funktioniert, aber deine Antwort war eher auf mein Ziel ausgerichtet. – dstar

8

Ich würde ein dict verwenden, zip erstellen, map und itertools.repeat:

from itertools import repeat 


data = ({k.strip(): v.strip() for _k, _v in map(lambda x: x.split(":"), dinner) 
    for k, v in zip(_k.split(","), repeat(_v))}) 

from pprint import pprint as pp 

pp(data) 

Ausgang:

{'bacon': 'Yes', 
'bologna': 'No', 
'broccoli': 'Maybe', 
'cake': 'No', 
'carrots': 'Yes', 
'cheese': 'No', 
'duck': 'Maybe', 
'hats': 'Definitely Not', 
'ice cream': 'Maybe', 
'marmalade': 'No', 
'motor oil': 'Definitely Not', 
'onions': 'Maybe', 
'peas': 'No', 
'pizza': 'Damn Right', 
'potatoes': 'Yes', 
'rats': 'Definitely Not', 
'seltzer': 'Yes', 
'sleeping': 'No Way', 
'spitting': 'No Way', 
'water': 'Yes', 
'whining': 'No Way'} 

Oder die dict-Konstruktor:

from itertools import repeat 

data = dict(map(str.strip, t) for _k, _v in map(lambda x: x.split(":"), dinner) 
      for t in zip(_k.split(","), repeat(_v))) 

from pprint import pprint as pp 

pp(data) 

Wenn Sie wirklich wollen eine Liste von Strings, können wir etwas ähnliches mit 0 tunund Verbinden der Teil:

from itertools import repeat, chain 

data = chain.from_iterable(map(":".join, zip(_k.split(","), repeat(_v))) 
          for _k, _v in map(lambda x: x.split(":"), dinner)) 


from pprint import pprint as pp 

pp(list(data)) 

Ausgang:

['cake: No', 
'peas: No', 
'cheese : No', 
'duck: Maybe', 
'broccoli: Maybe', 
'onions : Maybe', 
'motor oil : Definitely Not', 
'pizza : Damn Right', 
'ice cream : Maybe', 
'bologna : No', 
'potatoes: Yes', 
'bacon: Yes', 
'carrots: Yes', 
'water: Yes', 
'rats: Definitely Not', 
'hats : Definitely Not', 
'seltzer : Yes', 
'sleeping: No Way', 
'whining: No Way', 
'spitting : No Way', 
'marmalade : No'] 
1

Diese Arbeit kann:

def processList (aList): 
    finalList = [] 
    for aListEntry in aList: 
     aListEntry_entries = aListEntry.split(':') 
     aListEntry_list = aListEntry_entries[0].split(',') 
     for aListEntry_list_entry in aListEntry_list: 
      finalList.append(aListEntry_list_entry.strip() + ' : ' + aListEntry_entries[1].strip()) 
    return finalList 
1

Liste Comprehensions in Python bevorzugt werden (überprüfen zB this), aufgrund der besseren Lesbarkeit (zumindest für einige;).

Der Code demonstriert zwei Arten von Listenverstehen verschachteln, der erste ist im Grunde Verkettung der Operationen, der andere erzeugt eine Liste aus zwei verschachtelten Schleifen.

Wenn Sie Ihre Daten konsistent zu machen, indem ein Raum nach dem carrots, water hinzugefügt haben, können Sie loswerden zwei .strip() Anrufe bekommen;)

dinner = [ 
    'cake,peas,cheese : No', 
    'duck,broccoli,onions : Maybe', 
    'motor oil : Definitely Not', 
    'pizza : Damn Right', 
    'ice cream : Maybe', 
    'bologna : No', 
    'potatoes,bacon,carrots,water : Yes', 
    'rats,hats : Definitely Not', 
    'seltzer : Yes', 
    'sleeping,whining,spitting : No Way', 
    'marmalade : No' 
] 

prefs = [(pref, items.split(',')) for items, pref in [it.split(" : ") for it in dinner]] 
[" : ".join([item, pref]) for pref, items in prefs for item in items] 
Verwandte Themen