Ich habe mehrere Diktate / Schlüssel-Wert-Paare wie folgt:
d1 = {key1: x1, key2: y1}
d2 = {key1: x2, key2: y2}
Ich möchte, dass das Ergebnis ein neues Diktat ist (wenn möglich auf die effizienteste Weise):
d = {key1: (x1, x2), key2: (y1, y2)}
Eigentlich möchte ich, dass Ergebnis d ist:
d = {key1: (x1.x1attrib, x2.x2attrib), key2: (y1.y1attrib, y2.y2attrib)}
Wenn mir jemand zeigt, wie ich zum ersten Ergebnis komme, kann ich den Rest herausfinden.
python
dictionary
merge
Salil
quelle
quelle
Antworten:
vorausgesetzt, alle Schlüssel sind in allen Diktaten immer vorhanden:
ds = [d1, d2] d = {} for k in d1.iterkeys(): d[k] = tuple(d[k] for d in ds)
Hinweis: Verwenden Sie in Python 3.x den folgenden Code:
ds = [d1, d2] d = {} for k in d1.keys(): d[k] = tuple(d[k] for d in ds)
und wenn das dic numpy arrays enthält:
ds = [d1, d2] d = {} for k in d1.keys(): d[k] = np.concatenate(list(d[k] for d in ds))
quelle
d1
nicht korrekt ist (möglicherweise fehlen Schlüssel in anderen Diktaten).Hier ist eine allgemeine Lösung, die eine beliebige Anzahl von Wörterbüchern verarbeitet, mit Fällen, in denen Schlüssel nur in einigen Wörterbüchern enthalten sind:
from collections import defaultdict d1 = {1: 2, 3: 4} d2 = {1: 6, 3: 7} dd = defaultdict(list) for d in (d1, d2): # you can list as many input dicts as you want here for key, value in d.items(): dd[key].append(value) print(dd)
Zeigt an:
defaultdict(<type 'list'>, {1: [2, 6], 3: [4, 7]})
Um Ihre zu bekommen
.attrib
, wechseln Sie einfachappend(value)
zuappend(value.attrib)
quelle
tuple
nichtlist
.dict
daraus machen ,defaultdict
damit Sie ein normalesdict
Verhalten für nicht vorhandene Schlüssel usw. haben:dd = dict(dd)
Wenn Sie nur d1 und d2 haben,
from collections import defaultdict d = defaultdict(list) for a, b in d1.items() + d2.items(): d[a].append(b)
quelle
dict1 = {'m': 2, 'n': 4} dict2 = {'n': 3, 'm': 1}
Stellen Sie sicher, dass die Schlüssel in derselben Reihenfolge sind:
dict2_sorted = {i:dict2[i] for i in dict1.keys()} keys = dict1.keys() values = zip(dict1.values(), dict2_sorted.values()) dictionary = dict(zip(keys, values))
gibt:
{'m': (2, 1), 'n': (4, 3)}
quelle
values()
ist undefiniert, sodass Sie möglicherweise Werte von nicht verwandten Schlüsseln zusammenführen.sorted(d.items())
odersorted(d.keys())
erzielen.Hier ist ein Ansatz, den Sie verwenden können, der auch dann funktioniert, wenn beide Diktaturen nicht dieselben Schlüssel haben:
d1 = {'a':'test','b':'btest','d':'dreg'} d2 = {'a':'cool','b':'main','c':'clear'} d = {} for key in set(d1.keys() + d2.keys()): try: d.setdefault(key,[]).append(d1[key]) except KeyError: pass try: d.setdefault(key,[]).append(d2[key]) except KeyError: pass print d
Dies würde folgende Eingabe erzeugen:
{'a': ['test', 'cool'], 'c': ['clear'], 'b': ['btest', 'main'], 'd': ['dreg']}
quelle
set(d1.keys() + d2.keys())
geändert werdenset(list(d1.keys()) + list(d2.keys()))
(für Python 3.x)? Andernfalls wird einTypeError: unsupported operand type(s) for +: 'dict_keys' and 'dict_keys'
Fehler in python3.xPython 3.x Update
Von Eli Bendersky Antwort:
Python 3 entfernte dict.iteritems verwenden stattdessen dict.items. Siehe Python-Wiki: https://wiki.python.org/moin/Python3.0
from collections import defaultdict dd = defaultdict(list) for d in (d1, d2): for key, value in d.items(): dd[key].append(value)
quelle
Diese Methode führt zwei Wörter zusammen, auch wenn die Schlüssel in den beiden Wörterbüchern unterschiedlich sind:
def combine_dict(d1, d2): combined = {} for k in set(d1.keys()) | set(d2.keys()): combined[k] = tuple(d[k] for d in [d1, d2] if k in d) return combined
Beispiel:
d1 = { 'a': 1, 'b': 2, } d2` = { 'b': 'boat', 'c': 'car', } combine_dict(d1, d2) # Returns: { # 'a': (1,), # 'b': (2, 'boat'), # 'c': ('car',) # }
quelle
Angenommen, Sie haben die Liste ALLER Schlüssel (Sie können diese Liste erhalten, indem Sie alle Wörterbücher durchlaufen und deren Schlüssel abrufen). Nennen wir es
listKeys
. Ebenfalls:listValues
ist die Liste ALLER Werte für einen einzelnen Schlüssel, den Sie zusammenführen möchten.allDicts
: Alle Wörterbücher, die Sie zusammenführen möchten.result = {} for k in listKeys: listValues = [] #we will convert it to tuple later, if you want. for d in allDicts: try: fileList.append(d[k]) #try to append more values to a single key except: pass if listValues: #if it is not empty result[k] = typle(listValues) #convert to tuple, add to new dictionary with key k
quelle
def merge(d1, d2, merge): result = dict(d1) for k,v in d2.iteritems(): if k in result: result[k] = merge(result[k], v) else: result[k] = v return result d1 = {'a': 1, 'b': 2} d2 = {'a': 1, 'b': 3, 'c': 2} print merge(d1, d2, lambda x, y:(x,y)) {'a': (1, 1), 'c': 2, 'b': (2, 3)}
quelle
Als Ergänzung zu den Lösungen mit zwei Listen finden Sie hier eine Lösung zum Verarbeiten einer einzelnen Liste.
Eine Beispielliste (NetworkX-bezogen; hier zur besseren Lesbarkeit manuell formatiert):
ec_num_list = [((src, tgt), ec_num['ec_num']) for src, tgt, ec_num in G.edges(data=True)] print('\nec_num_list:\n{}'.format(ec_num_list)) ec_num_list: [((82, 433), '1.1.1.1'), ((82, 433), '1.1.1.2'), ((22, 182), '1.1.1.27'), ((22, 3785), '1.2.4.1'), ((22, 36), '6.4.1.1'), ((145, 36), '1.1.1.37'), ((36, 154), '2.3.3.1'), ((36, 154), '2.3.3.8'), ((36, 72), '4.1.1.32'), ...]
Beachten Sie die doppelten Werte für dieselben Kanten (definiert durch die Tupel). So sortieren Sie diese "Werte" mit den entsprechenden "Schlüsseln":
from collections import defaultdict ec_num_collection = defaultdict(list) for k, v in ec_num_list: ec_num_collection[k].append(v) print('\nec_num_collection:\n{}'.format(ec_num_collection.items())) ec_num_collection: [((82, 433), ['1.1.1.1', '1.1.1.2']), ## << grouped "values" ((22, 182), ['1.1.1.27']), ((22, 3785), ['1.2.4.1']), ((22, 36), ['6.4.1.1']), ((145, 36), ['1.1.1.37']), ((36, 154), ['2.3.3.1', '2.3.3.8']), ## << grouped "values" ((36, 72), ['4.1.1.32']), ...]
Konvertieren Sie diese Liste bei Bedarf in dikt:
ec_num_collection_dict = {k:v for k, v in zip(ec_num_collection, ec_num_collection)} print('\nec_num_collection_dict:\n{}'.format(dict(ec_num_collection))) ec_num_collection_dict: {(82, 433): ['1.1.1.1', '1.1.1.2'], (22, 182): ['1.1.1.27'], (22, 3785): ['1.2.4.1'], (22, 36): ['6.4.1.1'], (145, 36): ['1.1.1.37'], (36, 154): ['2.3.3.1', '2.3.3.8'], (36, 72): ['4.1.1.32'], ...}
Verweise
quelle
Von blubb Antwort:
Sie können das Tupel auch direkt mit Werten aus jeder Liste bilden
ds = [d1, d2] d = {} for k in d1.keys(): d[k] = (d1[k], d2[k])
Dies kann nützlich sein, wenn Sie eine bestimmte Bestellung für Ihre Tupel hatten
ds = [d1, d2, d3, d4] d = {} for k in d1.keys(): d[k] = (d3[k], d1[k], d4[k], d2[k]) #if you wanted tuple in order of d3, d1, d4, d2
quelle
Diese Bibliothek hat mir geholfen. Ich hatte eine Diktatliste verschachtelter Schlüssel mit demselben Namen, aber unterschiedlichen Werten. Jede andere Lösung überschrieb diese verschachtelten Schlüssel.
https://pypi.org/project/deepmerge/
from deepmerge import always_merger def process_parms(args): temp_list = [] for x in args: with open(x, 'r') as stream: temp_list.append(yaml.safe_load(stream)) return always_merger.merge(*temp_list)
quelle
Wenn Schlüssel verschachtelt sind:
d1 = { 'key1': { 'nkey1': 'x1' }, 'key2': { 'nkey2': 'y1' } } d2 = { 'key1': { 'nkey1': 'x2' }, 'key2': { 'nkey2': 'y2' } }
ds = [d1, d2] d = {} for k in d1.keys(): for k2 in d1[k].keys(): d.setdefault(k, {}) d[k].setdefault(k2, []) d[k][k2] = tuple(d[k][k2] for d in ds)
Ausbeuten:
{'key1': {'nkey1': ('x1', 'x2')}, 'key2': {'nkey2': ('y1', 'y2')}}
quelle
Eine kompakte Möglichkeit
d1={'a':1,'b':2} d2={'c':3,'d':4} context={**d1, **d2} context {'b': 2, 'c': 3, 'd': 4, 'a': 1}
quelle