2017-10-04 1 views
2

Ich habe diese Strukturliste:Python Liste der Liste der Listen verbinden mit der Taste

lst = [[['a', 100],['b', 200],['d', 325]],[['a', 50],['b', 250],['c', 75]]] 

‚lst‘ eine beliebige Anzahl von Teil-Listen enthalten (len (lst) kann größer sein als 2)

als Ausgang möchte ich:

output = [['a',100,50],['b',200,250],['c',0,75],['d',325,0]] 

Hier ist ein weiteres Beispiel:

lst = [[['a', 100],['b', 200],['d', 325]],[['a', 50],['b', 250],['c', 75]], [['a', 22], ['b', 10]]] 

output = [['a', 100, 50, 22],['b', 200, 250, 10], ['c', 0, 75, 0], ['d', 325, 0, 0]] 

Wie würden Sie das tun?

+0

warum einige Elemente null wie '['c', 0,75]' enthalten sollten? – RomanPerekhrest

+0

Wird 'lst' immer diese Struktur haben? IOW, wird es immer eine Liste von (Listen von (zwei Artikellisten)) sein? –

+0

@RomanPerekrest Es würde erscheinen, weil die erste Unterliste keinen "c" Schlüssel enthält, so dass das OP es standardmäßig auf 0 – Wondercricket

Antwort

2

Diese Aufgabe ein wenig einfacher wäre, wenn wir in lst verwendet, um eine Liste mit allen Buchstaben-Tasten hatte, aber es ist einfach genug, um sie zu extrahieren.

Meine Strategie besteht darin, die Unterlisten in Wörterbücher zu konvertieren. Das macht es einfach & effizient, den Wert zu nehmen, der mit jedem Schlüssel verbunden ist. Und die dict.get Methode ermöglicht es uns, einen Standardwert für fehlende Schlüssel anzugeben.

lst = [[['a', 100],['b', 200],['d', 325]],[['a', 50],['b', 250],['c', 75]]] 

# Convert outer sublists to dictionaries 
dicts = [*map(dict, lst)] 

# Get all the keys 
keys = set() 
for d in dicts: 
    keys.update(d.keys()) 

# Get data for each key from each dict, using 0 if a key is missing 
final = [[k] + [d.get(k, 0) for d in dicts] for k in sorted(keys)] 
print(final) 

Ausgang

[['a', 100, 50], ['b', 200, 250], ['c', 0, 75], ['d', 325, 0]] 

Wenn wir

lst = [[['a', 100],['b', 200],['d', 325]],[['a', 50],['b', 250],['c', 75]], [['a', 22], ['b', 10]]] 

verwenden dann die Ausgabe

[['a', 100, 50, 22], ['b', 200, 250, 10], ['c', 0, 75, 0], ['d', 325, 0, 0]] 

Wenn Sie dies auf Python 2 ausführen möchten, müssen Sie den Code, der die äußeren Unterlisten in Wörterbücher konvertiert, geringfügig ändern. Ändern Sie ihn auf

dicts = list(map(dict, lst)) 

das funktioniert richtig auf beiden Python 2 & 3. Und wenn Sie ausführen müssen, um es auf Python 2, geben Sie einfach

tun konnte
dicts = map(dict, lst) 

seit map in Python 2 zurück eine Liste, kein Iterator.

+0

Große Antwort, aber es könnte gut sein zu erwähnen, dass dies eine Python 3.5 Wondercricket

+0

@Wondercricket Die SO Python-Community-Richtlinie ist Python 3 anzunehmen, es sei denn, Python 2 ist explizit angegeben. ;) Aber ich werde einige relevante Informationen zu meiner Antwort hinzufügen. –

+0

Ich wusste nicht über diese Richtlinie, das ist gut zu wissen :) – Wondercricket

2

Sie können ein verwenden defaultdict:

from collections import defaultdict 
import itertools 
d = defaultdict(list) 
lst = [[['a', 100],['b', 200],['d', 325]],[['a', 50],['b', 250],['c', 75]]] 
for a, b in itertools.chain.from_iterable(lst): 
    d[a].append(b) 

new_lst = sorted([list(itertools.chain.from_iterable([[a], [0 for i in range(len(max(d.items(), key=lambda x:len(x[-1])))-len(b))]+b])) for a, b in d.items()]) 

Ausgang:

[['a', 100, 50], ['b', 200, 250], ['c', 0, 75], ['d', 0, 325]] 
+0

thx @ Ajax1234 Ihre Lösung funktioniert gut mit einer Liste von zwei Unterlisten, aber mit mehr als zwei Unterlisten wie [[['a', 100], ['b', 200], ['d', 325]], [['a', 50], ['b', 250], ['c', 75]], [['a', 22], ['b': 10]]]] Ich bekomme die Ausgabe: [ ['a', 100, 50, 22], ['b', 200, 250, 10], ['c', 0, 75], ['d', 0, 325]] Es sollte [['] sein a ', 100, 50, 22], [' b ', 200, 250, 10], [' c ', 0, 75, 0], [' d ', 325, 0, 0]] – gimba

2

Mit itertools.chain.from_iterable(), itertools.groupby() Funktionen und integrierte in next() Funktion:

import itertools 

lst = [ [['a', 100],['b', 200],['d', 325]],[['a', 50],['b', 250],['c', 75]], [['a', 22], ['b', 10]] ] 
lst_len = len(lst) 
sub_keys = [{k[0] for k in _} for _ in lst] 
result = [[k] + [next(g)[1] if k in sub_keys[i] else 0 for i in range(lst_len)] 
      for k,g in itertools.groupby(sorted(itertools.chain.from_iterable(lst), key=lambda x:x[0]), key=lambda x: x[0])] 

print(result) 

Der Ausgang:

[['a', 100, 50, 22], ['b', 200, 250, 10], ['c', 0, 75, 0], ['d', 325, 0, 0]] 
+0

@ PM2Ring, hinzugefügt für größere Listen – RomanPerekhrest

0

Das ist meine "long-Hand" Methode, musste ich einfach herausfinden, was ging weiter:

lst = [[['a', 100],['b', 200],['d', 325]], 
     [['a', 50],['b', 250],['c', 75]], 
     [['a', 22], ['b', 10]], 
     [['c', 110],['f', 200],['g', 425]], 
     [['a', 50],['f', 250],['h', 75]], 
     [['a', 32], ['b', 10]], ] 
nlist = [] 
store={} 
for n,j in enumerate(lst): 
    for i in j : 
     if i[0] in store : 
      store[i[0]].append(i[1]) 
     else : 
      store[i[0]] = nlist + [i[1]] 
    nlist += [0] 
    for k,v in store.items() : 
     if len(v) < n+1 : 
      store[k] = v + [0] 
print(store) 
result=[] 
for k,v in store.items(): 
    result += [[k] + v] 
print(sorted(result))