2017-12-15 151 views
5

Przez iterację na liście Pythona, chciałbym utworzyć słowniki listy, przy czym wartość każdego słownika również jest listą.Jak wygenerować listę słowników (z wartościami listy) z listy?

Struktura byłoby:

[{key1: [val1, val2]}, {key2: [val3, val4]}, {key3: [val5, val6]}, ...] 

zacznę z listy liczb całkowitych:

my_list = [3423, 77813, 12, 153, 1899] 

Dla każdego elementu na liście, to powinno stać się kluczowym słownika. Następnie dołączam dwie pozycje do wartości słownika (która jest listą). (Załóżmy, że obie pozycje są zawsze „pies” i „kot”)

Oto co wynik końcowy powinien wyglądać następująco:

[{3423:['dog', 'cat']}, {77813:['dog', 'cat']}, {12:['dog', 'cat']}, 
    {153:['dog', 'cat']}, {1899:['dog', 'cat']}] 

Moja próba na to ma wiele problemów:

for i in my_list: 
    d = {} ## create a dictionary 'd' 
    d[i] = [].append('dog') ## or `d[i] = ['dog'].append('cat')` 
    my_list.append(d) ## here is a bug 
    my_list.remove(i) ## remove the item from the list 
  1. nie podoba mi się, że muszę wymienić pusty słownik, i mieć je każdy nazwie to samo (tutaj d). Później chciałbym uzyskać dostęp do każdego z tych słowników za pomocą kluczy - nie dbam o ich nazwy.

  2. Nie wiem, jak rozsądnie dołączyć wiele elementów do wartości słownika, gdy faktycznie ma to być lista. Co jeśli chciałbym dodać kilka przedmiotów?

  3. Błąd polega na dołączaniu słownika do oryginalnej listy, a następnie usuwaniu elementu. Oczywiście, może to być rozwiązane z nowej listy:

    new_list = [] 
    for i in my_list: 
        d = {} 
        d[i] = [].append('dog') 
        new_list.append(d) 
        my_list.remove(i) 
    

ale czuje się bardzo niezdarny.

+1

Czy musisz użyć tej struktury, aby osiągnąć swój cel? Podejście obiektowe może zmniejszyć część złożoności, w zależności od tego, co próbujesz osiągnąć. Przynajmniej możesz rzucić okiem na '' defaultdict'' w module '' collections''. Następnie możesz zrobić '' list_dict = defaultdict (list) '', abyś wiedział, że każdy wpis w dyktacie jest już pustą listą. –

Odpowiedz

6

Jeśli chcesz coś naprawdę proste, można użyć wyrażeń listowych:

data = ['dog', 'cat'] 

my_list = [3423, 77813, 12, 153, 1899] 

result = [{k:data} for k in my_list] 

print(result) 
# [{3423: ['dog', 'cat']}, {77813: ['dog', 'cat']}, {12: ['dog', 'cat']}, {153: ['dog', 'cat']}, {1899: ['dog', 'cat']}] 

Dodatkowo, jest tu przykładem dodawania/usuwania wartości z bardzo dogodna defaultdict:

from collections import defaultdict 

my_list = [3423, 77813, 12, 153, 1899] 

new_list = [] 
for number in my_list: 

    # create the defaultdict here 
    d = defaultdict(list) 

    # add some data 
    d[number] += ['dog', 'cat', 'kitten'] 

    # remove some data 
    d[number].remove('kitten') 

    # append dictionary 
    new_list.append(dict(d)) 

print(new_list) 

Która wyjścia:

[{3423: ['dog', 'cat']}, {77813: ['dog', 'cat']}, {12: ['dog', 'cat']}, {153: ['dog', 'cat']}, {1899: ['dog', 'cat']}] 

Używanie defaultdict jest tutaj pomocny, ponieważ inicjalizuje każdy wpis w słowniku z pustą listą. Jeśli nie chcesz tego robić, możesz to osiągnąć przy użyciu zwykłego słownika, jak pokazano w pytaniu, ale to wymaga samodzielnego zainicjowania pustych list.

+0

Dlaczego miałoby to być "d [liczba] + = [" pies "," kot "," kotek "] zamiast" d [liczba] = ["pies", "kot", "kotek"] "? – EB2127

2

Można użyć podklasy collections.defaultdict słownika, aby przetwarzanie bardzo prosta:

from collections import defaultdict 
from pprint import pprint 

my_list = [3423, 77813, 12, 153, 1899] 
d = defaultdict(list) 

for i in my_list: 
    d[i].append('dog') 
    d[i].append('cat') 

d = dict(d) # Convert d into a regular dictionary (optional). 
pprint(d) 

wyjściowa:

{12: ['dog', 'cat'], 
153: ['dog', 'cat'], 
1899: ['dog', 'cat'], 
3423: ['dog', 'cat'], 
77813: ['dog', 'cat']} 

Oczywiście, jeśli wszystko zrobisz jest dołączyć te dwie rzeczy do siebie wprowadzeniu, byłoby nieco bardziej wydajne wykonywanie obu czynności w pojedynczej operacji, takiej jak:

for i in my_list: 
    d[i].extend(['dog', 'cat']) 
2

Jeśli chcesz używać funkcji sprawdzania list z różnymi wartościami dla każdego klawisza.

keys = ['key1', 'key2', 'key3'] 
values = [['val11', 'val12'], ['val21', 'val22'], ['val31', 'val32']] 

# This is what you want (if I understood correctly) 
dlist = [{x:values[i]} for i,x in enumerate(keys)] 

print(dlist) 

# When you want to add more dictionary to the list 
dlist.append({'key4': ['val41', 'val42']}) 

print(dlist) 

wyjściowa:

[{'key1':['val11','val12']}, {'key2':['val21','val22']}, {'key3':['val31','val32']}] 
[{'key1':['val11','val12']}, {'key2':['val21','val22']}, {'key3':['val31','val32']}, {'key4':['val41', 'val42']}] 
2

Nie trzeba usunąć, bez importowania dowolnego modułu zewnętrznego lub bez zbyt skomplikowane Można wystarczy wykonać ten wzór w czystym Pythonie

data = ['dog', 'cat'] 

my_list = [3423, 77813, 12, 153, 1899] 

new_data={} 
for item in my_list: 
    for sub_item in data: 

     if item not in new_data: 
      new_data[item]=[sub_item] 
     else: 
      new_data[item].append(sub_item) 

print(new_data) 

moc wyjściowa:

{153: ['dog', 'cat'], 1899: ['dog', 'cat'], 12: ['dog', 'cat'], 77813: ['dog', 'cat'], 3423: ['dog', 'cat']}