2016-02-21 12 views
7

Zrobiłem tę listę; każdy element jest ciągiem znaków, który zawiera przecinki (w niektórych przypadkach) i jelita grubego (zawsze):Korzystanie z Pythona Wyższe funkcje porządkowe do manipulowania listami

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' 
] 

Chciałbym utworzyć nową listę z jednym powyżej następująco:

['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'] 

ale Chciałbym wiedzieć, czy/jak to jest możliwe w linii lub dwóch z wydajnym kodem wykorzystującym głównie funkcje wyższego rzędu Pythona. Byłem próbuje go:

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

... produkuje to:

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

... ale mam zmaga się z dołączanie kawałek każdej struny po dwukropku powrotem na każdy pozycja.

+0

dlaczego jesteś zaniepokojony o długości kodu? To byłoby znacznie mniej do utrzymania w dłuższej perspektywie. – jpmc26

+0

@ jpmc26 Rozumiem, skąd przychodzisz i zgadzasz się. To dla mnie bardziej ćwiczenie eksploracyjne w zrozumieniu możliwości hofs Pythona. – dstar

Odpowiedz

3

Zakładając, że naprawdę trzeba go jako lista ciągów vs. słownika , który wygląda na lepszą strukturę danych.

Poprzez uproszczenie korzystania listowych można to zrobić:

>>> [[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']] 

obecnie zaledwie add się na listach:

>>> 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'] 

Albo po prostu spłaszczyć listę:

>>> [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' jest wbudowany jako' itertools.chain.from_iterable' – Caridorc

+0

@AChampion thank you. Kilka osób opublikowało świetny kod, który działa dobrze, ale twoja odpowiedź była bardziej zgodna z moim celem. – dstar

8

Chciałbym utworzyć dict stosując zip, map i 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) 

wyjściowa:

{'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'} 

Albo za pomocą konstruktora dict:

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) 

Jeśli naprawdę chcesz listę łańcuchów, możemy zrobić coś podobnego za pomocą itertools.chain i łącząc podciągi:

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)) 

wyjściowa:

['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

to może działać: Ułatwienia

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

Lista są preferowane w Pythonie (sprawdź np this), ze względu na lepszą czytelność (przynajmniej dla niektórych;).

Kod demonstruje dwa rodzaje zagnieżdżania ze zrozumieniem listy, pierwszy polega na łańcuchowym operowaniu, drugi tworzy jedną listę z dwóch zagnieżdżonych pętli.

Jeśli się bardziej spójne dane przez dodanie jednego miejsca po carrots, water, można pozbyć się z dwóch .strip() połączeń;)

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] 
Powiązane problemy