Πώς να συγχωνεύσει δύο λεξικά σε μια ενιαία έκφραση;

ψήφοι
3k

Έχω δύο λεξικά Python, και θέλω να γράψω ένα ενιαίο έκφραση που επιστρέφει αυτά τα δύο λεξικά, συγχωνεύονται. Η update()μέθοδος θα ήταν ό, τι χρειάζομαι, αν επιστρέψει λόγω του αντί τροποποίηση μιας dict επί τόπου.

>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> z = x.update(y)
>>> print(z)
None
>>> x
{'a': 1, 'b': 10, 'c': 11}

Πώς μπορώ να βρω αυτό το τελικό νέας dict στο z, όχι x;

(Για να είμαστε εξαιρετικά σαφείς, το τελευταίο-ένα-κερδίζει συγκρούσεις χειρισμό dict.update()είναι αυτό που ψάχνω, καθώς και.)

Δημοσιεύθηκε 02/09/2008 στις 06:44
πηγή χρήστη
Σε άλλες γλώσσες...                            


56 απαντήσεις

ψήφοι
40
x = {'a':1, 'b': 2}
y = {'b':10, 'c': 11}
z = dict(x.items() + y.items())
print z

Για τα στοιχεία με τα πλήκτρα και στις δύο λεξικά ( «β»), μπορείτε να καθορίσετε ποια καταλήγει στην έξοδο από τη θέση ότι μια τελευταία.

Απαντήθηκε 02/09/2008 στις 06:49
πηγή χρήστη

ψήφοι
1k

Στην περίπτωσή σας, τι μπορείτε να κάνετε είναι:

z = dict(x.items() + y.items())

Αυτό, όπως το θέλετε, βάλτε το τελικό dict σε z, και να κάνει η τιμή για το κλειδί bνα παρακαμφθεί σωστά από το δεύτερο ( yαξία) dict είναι:

>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> z = dict(x.items() + y.items())
>>> z
{'a': 1, 'c': 11, 'b': 10}

Εάν χρησιμοποιείτε Python 3, είναι μόνο λίγο πιο περίπλοκη. Για να δημιουργήσετε z:

>>> z = dict(list(x.items()) + list(y.items()))
>>> z
{'a': 1, 'c': 11, 'b': 10}
Απαντήθηκε 02/09/2008 στις 06:50
πηγή χρήστη

ψήφοι
542

Μία εναλλακτική:

z = x.copy()
z.update(y)
Απαντήθηκε 02/09/2008 στις 12:00
πηγή χρήστη

ψήφοι
269

Μια άλλη, πιο συνοπτική, η επιλογή:

z = dict(x, **y)

Σημείωση : αυτό έχει γίνει μια δημοφιλής απάντηση, αλλά είναι σημαντικό να επισημάνουμε ότι αν yέχει κάποια πλήκτρα μη-string, το γεγονός ότι αυτό λειτουργεί σε όλα είναι η κατάχρηση μιας λεπτομέρειας εφαρμογής CPython, και δεν λειτουργεί σε Python 3, ή σε PyPy, IronPython, ή Jython. Επίσης, Guido δεν είναι ένας ανεμιστήρας . Έτσι, δεν μπορώ να συστήσω αυτή την τεχνική για την προώθηση συμβατό ή πολλαπλή εφαρμογή φορητό κώδικα, το οποίο πραγματικά σημαίνει ότι θα πρέπει να αποφεύγεται εντελώς.

Απαντήθηκε 02/09/2008 στις 14:52
πηγή χρήστη

ψήφοι
85

Ήθελα κάτι παρόμοιο, αλλά με τη δυνατότητα να καθορίσετε τον τρόπο συγχωνεύτηκαν οι τιμές για τα διπλά πλήκτρα, γι 'αυτό hacked αυτό έξω (αλλά δεν το δοκιμάσει σε μεγάλο βαθμό). Προφανώς αυτό δεν είναι μια ενιαία έκφραση, αλλά είναι μια ενιαία κλήση της συνάρτησης.

def merge(d1, d2, merge_fn=lambda x,y:y):
    """
    Merges two dictionaries, non-destructively, combining 
    values on duplicate keys as defined by the optional merge
    function.  The default behavior replaces the values in d1
    with corresponding values in d2.  (There is no other generally
    applicable merge strategy, but often you'll have homogeneous 
    types in your dicts, so specifying a merge technique can be 
    valuable.)

    Examples:

    >>> d1
    {'a': 1, 'c': 3, 'b': 2}
    >>> merge(d1, d1)
    {'a': 1, 'c': 3, 'b': 2}
    >>> merge(d1, d1, lambda x,y: x+y)
    {'a': 2, 'c': 6, 'b': 4}

    """
    result = dict(d1)
    for k,v in d2.iteritems():
        if k in result:
            result[k] = merge_fn(result[k], v)
        else:
            result[k] = v
    return result
Απαντήθηκε 04/09/2008 στις 18:08
πηγή χρήστη

ψήφοι
165

Αυτό κατά πάσα πιθανότητα δεν θα είναι μια δημοφιλής απάντηση, αλλά είναι σχεδόν βέβαιο ότι δεν θέλετε να το κάνετε αυτό. Αν θέλετε ένα αντίγραφο που είναι μια συγχώνευση, στη συνέχεια, χρησιμοποιήστε αντίγραφο (ή deepcopy , ανάλογα με το τι θέλετε) και στη συνέχεια να ενημερώσετε. Οι δύο γραμμές του κώδικα είναι πολύ πιο ευανάγνωστο - περισσότερο Pythonic - από τη δημιουργία μοναδικής γραμμής .items () + .items (). Ρητή είναι καλύτερη από ό, τι υπονοείται.

Επιπλέον, όταν χρησιμοποιείτε .items () (προ Python 3.0), είστε δημιουργώντας μια νέα λίστα που περιέχει τα στοιχεία από την dict. Αν λεξικά σας είναι μεγάλο, τότε αυτό είναι πάρα πολλά γενικά έξοδα (δύο μεγάλες λίστες που θα πρέπει να απορρίπτονται αμέσως μόλις η νέα dict δημιουργείται). ενημέρωση () μπορεί να λειτουργήσει πιο αποτελεσματικά, επειδή μπορεί να τρέξει μέσα από το δεύτερο dict στοιχείο-προς-στοιχείο.

Από την άποψη του χρόνου :

>>> timeit.Timer("dict(x, **y)", "x = dict(zip(range(1000), range(1000)))\ny=dict(zip(range(1000,2000), range(1000,2000)))").timeit(100000)
15.52571702003479
>>> timeit.Timer("temp = x.copy()\ntemp.update(y)", "x = dict(zip(range(1000), range(1000)))\ny=dict(zip(range(1000,2000), range(1000,2000)))").timeit(100000)
15.694622993469238
>>> timeit.Timer("dict(x.items() + y.items())", "x = dict(zip(range(1000), range(1000)))\ny=dict(zip(range(1000,2000), range(1000,2000)))").timeit(100000)
41.484580039978027

IMO η μικρή επιβράδυνση μεταξύ των δύο πρώτων αξίζει τον κόπο για την αναγνωσιμότητα. Επιπλέον, τα επιχειρήματα λέξη-κλειδί για τη δημιουργία λεξικού προστέθηκε μόνο σε Python 2.3, ενώ αντίγραφο () και ενημέρωση () θα λειτουργήσει σε παλαιότερες εκδόσεις.

Απαντήθηκε 08/09/2008 στις 10:16
πηγή χρήστη

ψήφοι
114

Στην συνέχεια την απάντηση, σας ρώτησε για τη σχετική απόδοση αυτών των δύο εναλλακτικών λύσεων:

z1 = dict(x.items() + y.items())
z2 = dict(x, **y)

Την μηχανή μου, τουλάχιστον (ένα αρκετά συνηθισμένο x86_64 λειτουργία Python 2.5.2), εναλλακτική λύση z2δεν είναι μόνο μικρότερο και απλούστερο, αλλά και πολύ πιο γρήγορα. Μπορείτε να το επιβεβαιώσετε και μόνοι σας με τη χρήση της timeitμονάδας που έρχεται με την Python.

Παράδειγμα 1: ταυτόσημα λεξικά χαρτογράφηση 20 συναπτά ακέραιοι στους εαυτούς τους:

% python -m timeit -s 'x=y=dict((i,i) for i in range(20))' 'z1=dict(x.items() + y.items())'
100000 loops, best of 3: 5.67 usec per loop
% python -m timeit -s 'x=y=dict((i,i) for i in range(20))' 'z2=dict(x, **y)' 
100000 loops, best of 3: 1.53 usec per loop

z2κερδίζει με συντελεστή 3,5 ή έτσι. Διαφορετικά λεξικά φαίνεται να αποδώσει εντελώς διαφορετικά αποτελέσματα, αλλά z2φαίνεται πάντα να βγει μπροστά. (Αν έχετε αντιφατικά αποτελέσματα για την ίδια δοκιμή, δοκιμάστε περνώντας -rμε έναν αριθμό μεγαλύτερο από το προεπιλεγμένο 3.)

Παράδειγμα 2: μη-επικαλυπτόμενα λεξικά χαρτογράφηση 252 σύντομο χορδές να ακέραιοι και το αντίστροφο:

% python -m timeit -s 'from htmlentitydefs import codepoint2name as x, name2codepoint as y' 'z1=dict(x.items() + y.items())'
1000 loops, best of 3: 260 usec per loop
% python -m timeit -s 'from htmlentitydefs import codepoint2name as x, name2codepoint as y' 'z2=dict(x, **y)'               
10000 loops, best of 3: 26.9 usec per loop

z2 κερδίζει περίπου ένα συντελεστή 10. Αυτό είναι μια πολύ μεγάλη νίκη στο βιβλίο μου!

Μετά από τη σύγκριση των δύο αυτών, αναρωτήθηκα αν z1«s κακή απόδοση θα μπορούσε να αποδοθεί στην επιβάρυνση της κατασκευής των δύο λίστες στοιχείο, το οποίο με τη σειρά του με οδήγησε να αναρωτιέμαι αν αυτή η μεταβολή θα μπορούσε να λειτουργήσει καλύτερα:

from itertools import chain
z3 = dict(chain(x.iteritems(), y.iteritems()))

Μερικές γρήγορες δοκιμές, π.χ.

% python -m timeit -s 'from itertools import chain; from htmlentitydefs import codepoint2name as x, name2codepoint as y' 'z3=dict(chain(x.iteritems(), y.iteritems()))'
10000 loops, best of 3: 66 usec per loop

με οδηγούν στο συμπέρασμα ότι z3είναι κάπως πιο γρήγορα από ό, τι z1, αλλά δεν είναι σχεδόν τόσο γρήγορα όσο z2. Σίγουρα δεν αξίζει όλα τα επιπλέον πληκτρολόγηση.

Αυτή η συζήτηση εξακολουθεί να λείπει κάτι σημαντικό, που είναι η σύγκριση των επιδόσεων αυτών των εναλλακτικών λύσεων με την «προφανή» τρόπο συγχώνευση δύο λίστες: με τη χρήση της updateμεθόδου. Για να προσπαθήσει να κρατήσει τα πράγματα επί ίσοις όροις με τις εκφράσεις, κανένα από τα οποία τροποποιούν x ή y, Πάω να δημιουργήσετε ένα αντίγραφο του x, αντί της τροποποίησης είναι σε θέση, ως εξής:

z0 = dict(x)
z0.update(y)

Ένα τυπικό αποτέλεσμα:

% python -m timeit -s 'from htmlentitydefs import codepoint2name as x, name2codepoint as y' 'z0=dict(x); z0.update(y)'
10000 loops, best of 3: 26.9 usec per loop

Με άλλα λόγια, z0και z2φαίνεται να έχουν κατ 'ουσίαν όμοιες επιδόσεις. Πιστεύετε ότι αυτό θα μπορούσε να είναι σύμπτωση; Εγώ δεν κάνω ....

Στην πραγματικότητα, θα πήγαινα τόσο μακριά ώστε να ισχυρίζονται ότι είναι αδύνατο για καθαρό κώδικα Python για να κάνει κάτι καλύτερο από αυτό. Και αν μπορείτε να το κάνετε πολύ καλύτερα σε μια μονάδα επέκτασης C, φαντάζομαι οι λαοί Python θα μπορούσε κάλλιστα να ενδιαφέρονται για την ενσωμάτωση κωδικό σας (ή μια παραλλαγή προσέγγισή σας) στον πυρήνα Python. Python χρησιμοποιεί dictσε πολλά μέρη? βελτιστοποίηση των λειτουργιών του είναι μια μεγάλη υπόθεση.

Θα μπορούσατε επίσης να γράψετε αυτό ως

z0 = x.copy()
z0.update(y)

όπως ο Τόνι κάνει, αλλά (όπως ήταν αναμενόμενο), η διαφορά στο συμβολισμό αποδεικνύεται ότι δεν έχει καμία μετρήσιμη επίδραση στην απόδοση. Χρησιμοποιήστε όποιο φαίνεται δικαίωμα να σας. Φυσικά, αυτός είναι απολύτως σωστό να επισημάνω ότι η έκδοση δύο-δήλωση είναι πολύ πιο εύκολο να καταλάβει.

Απαντήθηκε 23/10/2008 στις 01:38
πηγή χρήστη

ψήφοι
54

Η καλύτερη εκδοχή θα μπορούσα να σκεφτείτε, ενώ δεν χρησιμοποιούν αντίγραφο θα είναι:

from itertools import chain
x = {'a':1, 'b': 2}
y = {'b':10, 'c': 11}
dict(chain(x.iteritems(), y.iteritems()))

Είναι πιο γρήγορα από ό, τι dict(x.items() + y.items()), αλλά όχι τόσο γρήγορα όσο n = copy(a); n.update(b), τουλάχιστον για CPython. Αυτή η έκδοση λειτουργεί επίσης σε Python 3 αν αλλάξετε iteritems()σε items(), η οποία γίνεται αυτόματα από το εργαλείο 2to3.

Προσωπικά μου αρέσει αυτή η έκδοση καλύτερα γιατί περιγράφει αρκετά καλά αυτό που θέλω σε ένα ενιαίο λειτουργικό σύνταξη. Το μόνο μικρό πρόβλημα είναι ότι δεν κάνει απολύτως προφανές ότι οι τιμές από την ομάδα υπερισχύει τιμές από το x, αλλά δεν πιστεύω ότι είναι δύσκολο να καταλάβω.

Απαντήθηκε 14/10/2010 στις 17:55
πηγή χρήστη

ψήφοι
34

Αν και η ερώτηση έχει ήδη απαντηθεί πολλές φορές, αυτή η απλή λύση στο πρόβλημα δεν έχει καταχωρηθεί ακόμα.

x = {'a':1, 'b': 2}
y = {'b':10, 'c': 11}
z4 = {}
z4.update(x)
z4.update(y)

Είναι τόσο γρήγορα όσο z0 και z2 κακό που αναφέρονται παραπάνω, αλλά είναι εύκολο να καταλάβει και την αλλαγή.

Απαντήθηκε 14/10/2011 στις 15:12
πηγή χρήστη

ψήφοι
24

Αν νομίζετε ότι λάμδα είναι κακό τότε διαβάστε περαιτέρω. Όπως ζητήθηκε, μπορείτε να γράψετε τη γρήγορη και μνήμη αποδοτική λύση με μια έκφραση:

x = {'a':1, 'b':2}
y = {'b':10, 'c':11}
z = (lambda a, b: (lambda a_copy: a_copy.update(b) or a_copy)(a.copy()))(x, y)
print z
{'a': 1, 'c': 11, 'b': 10}
print x
{'a': 1, 'b': 2}

Όπως προτείνεται παραπάνω, χρησιμοποιώντας δύο γραμμές ή γράφοντας μια λειτουργία είναι ίσως ο καλύτερος τρόπος να πάει.

Απαντήθηκε 23/11/2011 στις 16:08
πηγή χρήστη

ψήφοι
59

Αναδρομικά / βαθιά ενημερώσετε ένα dict

def deepupdate(original, update):
    """
    Recursively update a dict.
    Subdict's won't be overwritten but also updated.
    """
    for key, value in original.iteritems(): 
        if key not in update:
            update[key] = value
        elif isinstance(value, dict):
            deepupdate(value, update[key]) 
    return update

Επίδειξη:

pluto_original = {
    'name': 'Pluto',
    'details': {
        'tail': True,
        'color': 'orange'
    }
}

pluto_update = {
    'name': 'Pluutoo',
    'details': {
        'color': 'blue'
    }
}

print deepupdate(pluto_original, pluto_update)

έξοδοι:

{
    'name': 'Pluutoo',
    'details': {
        'color': 'blue',
        'tail': True
    }
}

Ευχαριστώ rednaw για αλλαγές.

Απαντήθηκε 29/11/2011 στις 09:52
πηγή χρήστη

ψήφοι
10

Ακόμα κι αν οι απαντήσεις ήταν καλό για αυτό το ρηχό λεξικό, καμία από τις μεθόδους που ορίζονται εδώ πραγματικά να κάνουμε μια βαθιά λεξικό συγχώνευση.

Παραδείγματα ακολουθούν:

a = { 'one': { 'depth_2': True }, 'two': True }
b = { 'one': { 'extra': False } }
print dict(a.items() + b.items())

Θα περίμενε κανείς ένα αποτέλεσμα κάτι σαν αυτό:

{ 'one': { 'extra': False', 'depth_2': True }, 'two': True }

Αντ 'αυτού, έχουμε αυτό:

{'two': True, 'one': {'extra': False}}

Το «ένα» εισόδου θα πρέπει να έχει «depth_2» και «έξτρα» ως αντικείμενα μέσα στο λεξικό του, αν ήταν πραγματικά μια συγχώνευση.

Χρησιμοποιώντας αλυσίδα, επίσης, δεν λειτουργεί:

from itertools import chain
print dict(chain(a.iteritems(), b.iteritems()))

Αποτελέσματα σε:

{'two': True, 'one': {'extra': False}}

Η βαθιά συγχώνευση ότι rcwesick έδωσε επίσης δημιουργεί το ίδιο αποτέλεσμα.

Ναι, αυτό θα λειτουργήσει για την συγχώνευση των δειγμάτων λεξικά, αλλά κανένα από αυτά δεν είναι ένα γενικό μηχανισμό για συγχώνευση. Θα ενημερώσω αργότερα φορά που γράφω μια μέθοδος που κάνει μια πραγματική συγχώνευση.

Απαντήθηκε 03/08/2012 στις 22:36
πηγή χρήστη

ψήφοι
31
def dict_merge(a, b):
  c = a.copy()
  c.update(b)
  return c

new = dict_merge(old, extras)

Μεταξύ αυτών των σκιερό και αμφίβολη απαντήσεις, αυτό το λαμπρό παράδειγμα είναι ο ένας και μοναδικός καλός τρόπος για να συγχωνεύσει DICTS σε Python, το οποίο εγκρίθηκε από το δικτάτορα για τη ζωή Guido van Rossum τον εαυτό του! Κάποιος άλλος πρότεινε το μισό από αυτό, αλλά δεν το έθεσε σε λειτουργία.

print dict_merge(
      {'color':'red', 'model':'Mini'},
      {'model':'Ferrari', 'owner':'Carl'})

δίνει:

{'color': 'red', 'owner': 'Carl', 'model': 'Ferrari'}
Απαντήθηκε 06/08/2012 στις 08:24
πηγή χρήστη

ψήφοι
12

δύο λεξικά

def union2(dict1, dict2):
    return dict(list(dict1.items()) + list(dict2.items()))

n λεξικά

def union(*dicts):
    return dict(itertools.chain.from_iterable(dct.items() for dct in dicts))

sumέχει κακή απόδοση. δείτε https://mathieularose.com/how-not-to-flatten-a-list-of-lists-in-python/

Απαντήθηκε 17/10/2012 στις 01:09
πηγή χρήστη

ψήφοι
70

Στην Python 3, μπορείτε να χρησιμοποιήσετε collections.ChainMap ποιες ομάδες πολλαπλών DICTS ή άλλες αντιστοιχίσεις μαζί για να δημιουργήσουν μια ενιαία, αναβαθμίσιμη άποψη:

>>> from collections import ChainMap
>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> z = ChainMap({}, y, x)
>>> for k, v in z.items():
        print(k, '-->', v)

a --> 1
b --> 10
c --> 11
Απαντήθηκε 28/04/2013 στις 02:15
πηγή χρήστη

ψήφοι
5

Χρησιμοποιώντας μια κατανόηση dict, μπορείτε να

x = {'a':1, 'b': 2}
y = {'b':10, 'c': 11}

dc = {xi:(x[xi] if xi not in list(y.keys()) 
           else y[xi]) for xi in list(x.keys())+(list(y.keys()))}

δίνει

>>> dc
{'a': 1, 'c': 11, 'b': 10}

Σημειώστε τη σύνταξη για if elseτο κατανόησης

{ (some_key if condition else default_key):(something_if_true if condition 
          else something_if_false) for key, value in dict_.items() }
Απαντήθηκε 27/05/2013 στις 08:04
πηγή χρήστη

ψήφοι
-3

Εδώ είναι μερικά κωδικό, φαίνεται να δουλεύει ok:

def merge(d1, d2, mode=0):
    if not type(d2) is dict:
        raise Exception("d2 is not a dict")

    if not type(d1) is dict:
        if mode == 0:
            raise Exception("d1 is not a dict")
        return d2

    result = dict(d1)

    for k, v in d2.iteritems():
        if k in result and type(v) is dict:
            result[k] = merge(result[k], v, 1)
        else:
            if mode == 1:
                result.update(d2)
            else:
                result[k] = v
    return result
Απαντήθηκε 11/07/2013 στις 06:13
πηγή χρήστη

ψήφοι
8

Αντλώντας ιδέες εδώ και αλλού έχω κατανοήσει μια λειτουργία:

def merge(*dicts, **kv): 
      return { k:v for d in list(dicts) + [kv] for k,v in d.items() }

Χρήση (δοκιμάστηκε σε Python 3):

assert (merge({1:11,'a':'aaa'},{1:99, 'b':'bbb'},foo='bar')==\
    {1: 99, 'foo': 'bar', 'b': 'bbb', 'a': 'aaa'})

assert (merge(foo='bar')=={'foo': 'bar'})

assert (merge({1:11},{1:99},foo='bar',baz='quux')==\
    {1: 99, 'foo': 'bar', 'baz':'quux'})

assert (merge({1:11},{1:99})=={1: 99})

Θα μπορούσατε να χρησιμοποιήσετε ένα λάμδα αντ 'αυτού.

Απαντήθηκε 19/07/2013 στις 04:49
πηγή χρήστη

ψήφοι
14

Κατάχρηση οδηγεί σε λύση του ενός έκφρασης για την απάντηση του Ματθαίου :

>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> z = (lambda f=x.copy(): (f.update(y), f)[1])()
>>> z
{'a': 1, 'c': 11, 'b': 10}

Είπατε ότι ήθελε μια έκφραση, γι 'αυτό καταχραστεί lambdaνα δεσμεύσει ένα όνομα, και πλειάδες να παρακάμψουν το όριο του ενός έκφραση λάμδα του. Μη διστάσετε να μαζεύομαι.

Θα μπορούσατε επίσης να το κάνετε αυτό, φυσικά, αν δεν νοιάζονται για αντιγραφή:

>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> z = (x.update(y), x)[1]
>>> z
{'a': 1, 'b': 10, 'c': 11}
Απαντήθηκε 07/08/2013 στις 20:23
πηγή χρήστη

ψήφοι
1

**δημιουργεί ένα ενδιάμεσο dict, πράγμα που σημαίνει ότι ο συνολικός αριθμός των αντιγράφων είναι στην πραγματικότητα υψηλότερα κάνει τη dict(one, **two)μορφή, αλλά όλα όσα συμβαίνουν στο C έτσι ώστε να εξακολουθούν να είναι γενικά πιο γρήγορα από ό, τι πρόκειται να itertools, εκτός αν υπάρχει ένας τεράστιος αριθμός των αντιγράφων (ή, μάλλον, αν τα αντίγραφα είναι πολύ ακριβά). Όπως πάντα, αν πραγματικά νοιάζονται για την ταχύτητα θα πρέπει να λήξει το χρονικό περίπτωση χρήσης σας.

Χρονισμού στον Python 2.7.3 με ένα άδειο dict:

$ python -m timeit "dict({}, **{})"
1000000 loops, best of 3: 0.405 usec per loop

$ python -m timeit -s "from itertools import chain" \
    "dict(chain({}.iteritems(), {}.iteritems()))"
1000000 loops, best of 3: 1.18 usec per loop

Με 10.000 (μικρό) στοιχεία:

$ python -m timeit -s 'd = {i: str(i) for i in xrange(10000)}' \
    "dict(d, **d)"
1000 loops, best of 3: 550 usec per loop

$ python -m timeit -s "from itertools import chain" -s 'd = {i: str(i) for i in xrange(10000)}' \
    "dict(chain(d.iteritems(), d.iteritems()))"
1000 loops, best of 3: 1.11 msec per loop

Με 100.000 αντικείμενα:

$ python -m timeit -s 'd = {i: str(i) for i in xrange(100000)}' \
    "dict(d, **d)"
10 loops, best of 3: 19.6 msec per loop

$ python -m timeit -s "from itertools import chain" -s 'd = {i: str(i) for i in xrange(100000)}' \
    "dict(chain(d.iteritems(), d.iteritems()))"
10 loops, best of 3: 20.1 msec per loop

Με 1.000.000 στοιχεία:

$ python -m timeit -s 'd = {i: str(i) for i in xrange(1000000)}' \
    "dict(d, **d)"
10 loops, best of 3: 273 msec per loop

$ python -m timeit -s "from itertools import chain" -s 'd = {i: str(i) for i in xrange(1000000)}' \
    "dict(chain(d.iteritems(), d.iteritems()))"
10 loops, best of 3: 233 msec per loop
Απαντήθηκε 06/09/2013 στις 19:18
πηγή χρήστη

ψήφοι
18

Σε python3, η itemsμέθοδος δεν επιστρέφει μια λίστα , αλλά μάλλον μια άποψη , η οποία λειτουργεί σαν ένα σύνολο. Σε αυτή την περίπτωση θα πρέπει να πάρει το σετ Ένωση από τη συνένωση με +δεν θα λειτουργήσει:

dict(x.items() | y.items())

Για python3-συμπεριφορά στην έκδοση 2.7, η viewitemsμέθοδος θα πρέπει να λειτουργεί στη θέση του items:

dict(x.viewitems() | y.viewitems())

Προτιμώ αυτό το συμβολισμό ούτως ή άλλως, δεδομένου ότι φαίνεται πιο φυσικό να σκεφτείτε από το ως επιχείρηση σύνολο της Ένωσης και όχι συνένωση (όπως ο τίτλος δείχνει).

Επεξεργασία:

Ένα ζευγάρι περισσότερα σημεία για python 3. Κατ 'αρχάς, σημειώστε ότι το dict(x, **y)τέχνασμα δεν θα λειτουργήσει σε python 3, εκτός εάν τα κλειδιά στο yείναι χορδές.

Επίσης, Chainmap Raymond Hettinger του απάντηση είναι αρκετά κομψό, δεδομένου ότι μπορεί να πάρει ένα αυθαίρετο αριθμό των DICTS ως επιχειρήματα, αλλά από τα έγγραφα που μοιάζει να κοιτάζει διαδοχικά σε μια λίστα με όλες τις DICTS για κάθε αναζήτηση:

Αναζητήσεις αναζήτηση των βαθύτερων αντιστοιχίσεις διαδοχικά μέχρι να βρεθεί το κλειδί.

Αυτό μπορεί να σας επιβραδύνει, αν έχετε πολλές αναζητήσεις στην εφαρμογή σας:

In [1]: from collections import ChainMap
In [2]: from string import ascii_uppercase as up, ascii_lowercase as lo; x = dict(zip(lo, up)); y = dict(zip(up, lo))
In [3]: chainmap_dict = ChainMap(y, x)
In [4]: union_dict = dict(x.items() | y.items())
In [5]: timeit for k in union_dict: union_dict[k]
100000 loops, best of 3: 2.15 µs per loop
In [6]: timeit for k in chainmap_dict: chainmap_dict[k]
10000 loops, best of 3: 27.1 µs per loop

Έτσι, περίπου μια τάξη μεγέθους πιο αργή για αναζητήσεις. Είμαι οπαδός της Chainmap, αλλά φαίνεται λιγότερο πρακτική, όπου μπορεί να υπάρχουν πολλές αναζητήσεις.

Απαντήθηκε 09/10/2013 στις 17:09
πηγή χρήστη

ψήφοι
9
>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> x, z = dict(x), x.update(y) or x
>>> x
{'a': 1, 'b': 2}
>>> y
{'c': 11, 'b': 10}
>>> z
{'a': 1, 'c': 11, 'b': 10}
Απαντήθηκε 13/11/2013 στις 08:01
πηγή χρήστη

ψήφοι
6

Το πρόβλημα που έχω με λύσεις που μέχρι σήμερα είναι ότι, στη νέα λεξικό, η τιμή για το κλειδί «β» είναι 10, αλλά, με τον τρόπο σκέψης μου, θα πρέπει να είναι 12. Υπό το πρίσμα αυτό, παρουσιάζω τα εξής:

import timeit

n=100000
su = """
x = {'a':1, 'b': 2}
y = {'b':10, 'c': 11}
"""

def timeMerge(f,su,niter):
    print "{:4f} sec for: {:30s}".format(timeit.Timer(f,setup=su).timeit(n),f)

timeMerge("dict(x, **y)",su,n)
timeMerge("x.update(y)",su,n)
timeMerge("dict(x.items() + y.items())",su,n)
timeMerge("for k in y.keys(): x[k] = k in x and x[k]+y[k] or y[k] ",su,n)

#confirm for loop adds b entries together
x = {'a':1, 'b': 2}
y = {'b':10, 'c': 11}
for k in y.keys(): x[k] = k in x and x[k]+y[k] or y[k]
print "confirm b elements are added:",x

Αποτελέσματα:

0.049465 sec for: dict(x, **y)
0.033729 sec for: x.update(y)                   
0.150380 sec for: dict(x.items() + y.items())   
0.083120 sec for: for k in y.keys(): x[k] = k in x and x[k]+y[k] or y[k]

confirm b elements are added: {'a': 1, 'c': 11, 'b': 12}
Απαντήθηκε 03/12/2013 στις 16:11
πηγή χρήστη

ψήφοι
2

Έχω μια λύση η οποία δεν έχει καθοριστεί εδώ (Man I LOVE python) :-)

z = {}
z.update(x) or z.update(y)

Αυτό δεν θα ενημερώσει x, καθώς και y. Εκτέλεση? Δεν νομίζω ότι θα είναι τρομερά αργή :-)

ΣΗΜΕΙΩΣΗ: Είναι υποτίθεται ότι είναι «ή» λειτουργία και όχι «και» λειτουργία. Επεξεργασία για να διορθώσετε τον κωδικό.

Απαντήθηκε 05/12/2013 στις 06:02
πηγή χρήστη

ψήφοι
4

Είναι τόσο ανόητο που .updateεπιστρέφει τίποτα.
Απλά χρησιμοποιήστε μια απλή λειτουργία βοηθός για την επίλυση του προβλήματος:

def merge(dict1,*dicts):
    for dict2 in dicts:
        dict1.update(dict2)
    return dict1

Παραδείγματα:

merge(dict1,dict2)
merge(dict1,dict2,dict3)
merge(dict1,dict2,dict3,dict4)
merge({},dict1,dict2)  # this one returns a new copy
Απαντήθηκε 01/03/2014 στις 23:44
πηγή χρήστη

ψήφοι
1

Η ένωση των δύο λεξικών του Ε.Π. θα ήταν κάτι σαν:

{'a': 1, 'b': 2, 10, 'c': 11}

Συγκεκριμένα, η ένωση των δύο οντοτήτων ( xκαι y) περιέχει όλα τα στοιχεία του xή / και y. Δυστυχώς, αυτό το ΕΠ ζητά δεν είναι μια ένωση, παρά τον τίτλο της θέσης.

κωδικό μου παρακάτω δεν είναι ούτε κομψή ούτε ένα σκάφος της γραμμής, αλλά πιστεύω ότι είναι συνεπής με την έννοια της ένωσης.

Από το παράδειγμα του ΕΠ:

x = {'a':1, 'b': 2}
y = {'b':10, 'c': 11}

z = {}
for k, v in x.items():
    if not k in z:
        z[k] = [(v)]
    else:
        z[k].append((v))
for k, v in y.items():
    if not k in z:
        z[k] = [(v)]
    else:
        z[k].append((v))

{'a': [1], 'b': [2, 10], 'c': [11]}

Είτε κάποιος θέλει λίστες θα μπορούσε να αλλάξει, αλλά τα παραπάνω θα λειτουργήσει αν ένα λεξικό περιέχει λίστες (και ένθετες λίστες) ως τιμές είτε σε λεξικό.

Απαντήθηκε 30/09/2014 στις 01:36
πηγή χρήστη

ψήφοι
3k

Πώς μπορώ να συγχωνεύσετε δύο λεξικά Python σε μια ενιαία έκφραση;

Για λεξικά xκαι y, zγίνεται μια νέα λεξικό με τιμές από yτην αντικατάσταση εκείνων που προέρχονται από x.

  • Σε Python 3.5 ή μεγαλύτερη,:

    z = {**x, **y}
    
  • Στην Python 2, (ή 3.4 ή χαμηλότερο) γράφετε λειτουργία:

    def merge_two_dicts(x, y):
        z = x.copy()   # start with x's keys and values
        z.update(y)    # modifies z with y's keys and values & returns None
        return z
    

    και

    z = merge_two_dicts(x, y)
    

Εξήγηση

Ας υποθέσουμε ότι έχετε δύο DICTS και θέλετε να τις συγχωνεύσει σε μια νέα dict χωρίς να αλλοιώνει τα αρχικά DICTS:

x = {'a': 1, 'b': 2}
y = {'b': 3, 'c': 4}

Το επιθυμητό αποτέλεσμα είναι να πάρετε ένα νέο λεξικό ( z) με τις τιμές συγχωνεύονται και οι τιμές του δεύτερου dict για την αντικατάσταση εκείνων που προέρχονται από την πρώτη.

>>> z
{'a': 1, 'b': 3, 'c': 4}

Μια νέα σύνταξη για αυτό, προτείνεται στην PEP 448 και διατίθενται ως της Python 3.5 , είναι

z = {**x, **y}

Και είναι πράγματι μια ενιαία έκφραση. Τώρα που δείχνουν όπως εφαρμόζεται στο χρονοδιάγραμμα απελευθέρωσης για 3,5, PEP 478 , και τώρα έχει κάνει τον τρόπο του σε Τι νέο υπάρχει στην Python 3.5 του εγγράφου.

Ωστόσο, δεδομένου ότι πολλοί οργανισμοί βρίσκονται ακόμη σε Python 2, μπορεί να θέλετε να το κάνετε αυτό σε ένα συμβατό τρόπο. Το κλασικό Pythonic τρόπο, διατίθεται σε Python 2 και Python 3,0-3,4, είναι να το κάνει αυτό ως μια διαδικασία δύο σταδίων:

z = x.copy()
z.update(y) # which returns None since it mutates z

Και στις δύο προσεγγίσεις, yθα έρθει δεύτερη και τις αξίες της θα αντικαταστήσουν xτις αξίες «s, έτσι 'b'θα επισημάνει 3στον τελικό μας αποτέλεσμα.

Δεν έχει στην Python 3.5, αλλά θέλουν μια ενιαία έκφραση

Εάν δεν είστε ακόμα στην Python 3.5, ή πρέπει να γράψετε τα πίσω-συμβατό κώδικα, και θέλετε αυτό σε μια ενιαία έκφραση , η πιο αποδοτικοί, ενώ σωστή προσέγγιση είναι να το βάλετε σε λειτουργία:

def merge_two_dicts(x, y):
    """Given two dicts, merge them into a new dict as a shallow copy."""
    z = x.copy()
    z.update(y)
    return z

και στη συνέχεια να έχετε μια ενιαία έκφραση:

z = merge_two_dicts(x, y)

Μπορείτε επίσης να κάνετε μια λειτουργία για να συγχωνεύσει ένα απροσδιόριστο αριθμό DICTS, από το μηδέν σε ένα πολύ μεγάλο αριθμό:

def merge_dicts(*dict_args):
    """
    Given any number of dicts, shallow copy and merge into a new dict,
    precedence goes to key value pairs in latter dicts.
    """
    result = {}
    for dictionary in dict_args:
        result.update(dictionary)
    return result

Η λειτουργία αυτή θα λειτουργήσει στην Python 2 και 3 για όλες τις DICTS. π.χ. δοθεί DICTS aσε g:

z = merge_dicts(a, b, c, d, e, f, g) 

και τα βασικά ζεύγη αξία gθα υπερισχύουν DICTS aνα f, και ούτω καθεξής.

Κριτικές από άλλες απαντήσεις

Μην χρησιμοποιείτε αυτό που βλέπετε στην πρώην αποδεκτή απάντηση:

z = dict(x.items() + y.items())

Στην Python 2, μπορείτε να δημιουργήσετε δύο λίστες στη μνήμη για κάθε dict, δημιουργήστε έναν τρίτο κατάλογο στη μνήμη με μήκος ίσο με το μήκος των δύο πρώτων μαζί, και στη συνέχεια απορρίψει τους τρεις λίστες για να δημιουργήσετε το dict. Στην Python 3, θα αποτύχει γιατί θέλετε να προσθέσετε δύο dict_itemsαντικείμενα μεταξύ τους, όχι δύο λίστες -

>>> c = dict(a.items() + b.items())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'dict_items' and 'dict_items'

και θα πρέπει να δημιουργήσετε ρητά τους ως λίστες, π.χ. z = dict(list(x.items()) + list(y.items())). Αυτή είναι μια σπατάλη των πόρων και τη δύναμη υπολογισμού.

Ομοίως, λαμβάνοντας την ένωση του items()στην Python 3 ( viewitems()στην Python 2.7) θα αποτύχει επίσης όταν οι τιμές είναι unhashable αντικείμενα (όπως οι πίνακες, για παράδειγμα). Ακόμα κι αν οι τιμές σας είναι hashable, δεδομένου ότι τα σύνολα είναι σημασιολογικά επιτυγχάνεται με την εντολή, η συμπεριφορά είναι απροσδιόριστη σε σχέση με το προβάδισμα. Επομένως, μην το κάνετε αυτό:

>>> c = dict(a.items() | b.items())

Αυτό το παράδειγμα δείχνει τι συμβαίνει όταν οι τιμές είναι unhashable:

>>> x = {'a': []}
>>> y = {'b': []}
>>> dict(x.items() | y.items())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

Εδώ είναι ένα παράδειγμα όπου y θα πρέπει να έχει το προβάδισμα, αλλά, αντίθετα, η τιμή από το x διατηρείται λόγω της αυθαίρετης σειρά των συνόλων:

>>> x = {'a': 2}
>>> y = {'a': 1}
>>> dict(x.items() | y.items())
{'a': 2}

Ένα άλλο hack δεν πρέπει να χρησιμοποιήσετε:

z = dict(x, **y)

Αυτό χρησιμοποιεί το dictκατασκευαστή, και είναι πολύ γρήγορη και μνήμη αποδοτική (έστω και λίγο περισσότερο, από ό, τι διαδικασία δύο σταδίων μας), αλλά αν δεν ξέρετε ακριβώς τι συμβαίνει εδώ (δηλαδή, η δεύτερη dict είναι να περάσει ως επιχειρήματα λέξη-κλειδί για την dict κατασκευαστή), είναι δύσκολο να διαβάσει, δεν είναι η προβλεπόμενη χρήση του, και γι 'αυτό δεν είναι Pythonic.

Εδώ είναι ένα παράδειγμα της χρήσης που αποκατάσταση σε Django .

Οι DICTS την πρόθεση να λάβει hashable κλειδιά (π.χ. frozensets ή πλειάδες), αλλά αυτή η μέθοδος αποτυγχάνει σε Python 3, όταν τα πλήκτρα δεν είναι χορδές.

>>> c = dict(a, **b)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: keyword arguments must be strings

Από τη λίστα , Guido van Rossum, ο δημιουργός της γλώσσας, έγραψε:

Είμαι καλά με δηλώνοντας dict ({}, ** {1: 3}) παράνομες, δεδομένου ότι μετά από όλα είναι κατάχρηση του ** μηχανισμού.

και

Προφανώς dict (x, y **) πηγαίνει γύρω από το "δροσερό hack" για "x.update κλήσης (y) και να επιστρέψει x". Προσωπικά θεωρώ ότι είναι πιο κατακριτέα από ό, τι δροσερό.

Είναι κατανόηση μου (καθώς και η κατανόηση του δημιουργού της γλώσσας ) ότι η προβλεπόμενη χρήση του για dict(**y)είναι για τη δημιουργία DICTS για λόγους αναγνωσιμότητας, όπως:

dict(a=1, b=10, c=11)

αντί

{'a': 1, 'b': 10, 'c': 11}

Απάντηση σε σχόλιο

Παρά τα όσα λέει ο Guido, dict(x, **y)είναι σύμφωνη με τις προδιαγραφές dict, η οποία btw. Λειτουργεί τόσο για Python 2 και 3. Το γεγονός ότι αυτό λειτουργεί μόνο για τα κλειδιά string είναι μια άμεση συνέπεια του τρόπου με λέξη-κλειδί παραμέτρων λειτουργεί και όχι μια μικρής Εντοπίστε της dict. Ούτε χρησιμοποιεί το ** χειριστή σε αυτόν τον τόπο κατάχρηση του μηχανισμού, στην πραγματικότητα ** σχεδιάστηκε ακριβώς για να περάσει DICTS ως λέξεις-κλειδιά.

Και πάλι, αυτό δεν λειτουργεί για 3 όταν κλειδιά είναι μη-χορδές. Η σιωπηρή σύμβαση καλώντας είναι ότι ονομάτων λάβει συνηθισμένο DICTS, ενώ οι χρήστες πρέπει να περάσουν μόνο τα επιχειρήματα-κλειδιά που είναι χορδές. Όλα τα άλλα callables να επιβληθεί. dictέσπασε αυτή η συνέπεια στην Python 2:

>>> foo(**{('a', 'b'): None})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: foo() keywords must be strings
>>> dict(**{('a', 'b'): None})
{('a', 'b'): None}

Αυτή η ασυνέπεια κακή δόθηκε άλλες εφαρμογές Python (Pypy, Jython, IronPython). Έτσι, καθορίστηκε σε Python 3, καθώς αυτή η χρήση θα μπορούσε να είναι ένα σπάσιμο αλλαγή.

Θα σας καταθέσω ότι είναι κακόβουλο ανικανότητα να γράψει σκόπιμα κώδικα που λειτουργεί μόνο σε μία έκδοση της γλώσσας ή ότι μόνο τα έργα δίνονται ορισμένες αυθαίρετες περιορισμούς.

Ένα άλλο σχόλιο:

dict(x.items() + y.items()) εξακολουθεί να είναι η πιο ευανάγνωστο λύση για την Python 2. μετρήσεις αναγνωσιμότητας.

Η απάντησή μου: merge_two_dicts(x, y)Φαίνεται πραγματικά πολύ πιο σαφής για μένα, αν είμαστε ανησυχεί πραγματικά για την αναγνωσιμότητα. Και δεν είναι απόλυτα συμβατά, όπως Python 2 ολοένα και περισσότερο καταργηθεί.

Λιγότερο performant Αλλά Σωστή Ad-hocs

Αυτές οι προσεγγίσεις είναι λιγότερο αποδοτικοί, αλλά θα παρέχει τη σωστή συμπεριφορά. Θα είναι πολύ λιγότερο αποδοτικοί από ό, τι copyκαι updateή το νέο αποσυσκευασία επειδή επαναλαμβάνεται σε κάθε ζεύγος κλειδιού-τιμής σε ένα υψηλότερο επίπεδο αφαίρεσης, αλλά κάνουν σέβονται την σειρά προτεραιότητας (τελευταία DICTS έχουν προτεραιότητα)

Μπορείτε επίσης να συνδέετε τις DICTS με το χέρι μέσα σε ένα κατανόησης dict:

{k: v for d in dicts for k, v in d.items()} # iteritems in Python 2.7

ή σε python 2.6 (και ίσως ήδη από το 2.4, όταν εισήχθησαν εκφράσεις γεννήτρια):

dict((k, v) for d in dicts for k, v in d.items())

itertools.chain Θα αλυσίδα των iterators πάνω από τα ζεύγη κλειδιών-τιμών με τη σωστή σειρά:

import itertools
z = dict(itertools.chain(x.iteritems(), y.iteritems()))

Ανάλυση Απόδοσης

Είμαι μόνο πρόκειται να κάνει την ανάλυση των επιδόσεων των χρήσεων που είναι γνωστό ότι συμπεριφέρονται σωστά.

import timeit

Η ακόλουθη γίνεται στο Ubuntu 14.04

Στην Python 2.7 (σύστημα Python):

>>> min(timeit.repeat(lambda: merge_two_dicts(x, y)))
0.5726828575134277
>>> min(timeit.repeat(lambda: {k: v for d in (x, y) for k, v in d.items()} ))
1.163769006729126
>>> min(timeit.repeat(lambda: dict(itertools.chain(x.iteritems(), y.iteritems()))))
1.1614501476287842
>>> min(timeit.repeat(lambda: dict((k, v) for d in (x, y) for k, v in d.items())))
2.2345519065856934

Στην Python 3.5 (deadsnakes PPA):

>>> min(timeit.repeat(lambda: {**x, **y}))
0.4094954460160807
>>> min(timeit.repeat(lambda: merge_two_dicts(x, y)))
0.7881555100320838
>>> min(timeit.repeat(lambda: {k: v for d in (x, y) for k, v in d.items()} ))
1.4525277839857154
>>> min(timeit.repeat(lambda: dict(itertools.chain(x.items(), y.items()))))
2.3143140770262107
>>> min(timeit.repeat(lambda: dict((k, v) for d in (x, y) for k, v in d.items())))
3.2069112799945287

Πόροι για Λεξικά

Απαντήθηκε 10/11/2014 στις 20:11
πηγή χρήστη

ψήφοι
41

Python 3.5 (PEP 448) επιτρέπει ένα καλύτερο επιλογή σύνταξη:

x = {'a': 1, 'b': 1}
y = {'a': 2, 'c': 2}
final = {**x, **y} 
final
# {'a': 2, 'b': 1, 'c': 2}

Ή ακόμη και

final = {'a': 1, 'b': 1, **x, **y}
Απαντήθηκε 26/02/2015 στις 19:27
πηγή χρήστη

ψήφοι
3
a = {1: 2, 3: 4, 5: 6}
b = {7:8, 1:2}
combined = dict(a.items() + b.items())
print combined
Απαντήθηκε 20/03/2015 στις 22:06
πηγή χρήστη

ψήφοι
5

Αυτό μπορεί να γίνει με ένα μόνο dict κατανόηση:

>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> { key: y[key] if key in y else x[key]
      for key in set(x) + set(y)
    }

Κατά τη γνώμη μου η καλύτερη απάντηση για το τμήμα «ενιαία έκφραση», όπως είναι χωρίς έξτρα λειτουργίες που απαιτούνται, και είναι σύντομη.

Απαντήθηκε 17/07/2015 στις 13:47
πηγή χρήστη

ψήφοι
13

Απλή λύση χρησιμοποιώντας itertools που διατηρεί παραγγελίας (τελευταίοι DICTS έχουν προτεραιότητα)

import itertools as it
merge = lambda *args: dict(it.chain.from_iterable(it.imap(dict.iteritems, args)))

Και είναι η χρήση:

>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> merge(x, y)
{'a': 1, 'b': 10, 'c': 11}

>>> z = {'c': 3, 'd': 4}
>>> merge(x, y, z)
{'a': 1, 'b': 10, 'c': 3, 'd': 4}
Απαντήθηκε 04/08/2015 στις 13:54
πηγή χρήστη

ψήφοι
5
from collections import Counter
dict1 = {'a':1, 'b': 2}
dict2 = {'b':10, 'c': 11}
result = dict(Counter(dict1) + Counter(dict2))

Αυτό θα πρέπει να λύσει το πρόβλημά σας.

Απαντήθηκε 30/11/2015 στις 11:04
πηγή χρήστη

ψήφοι
16

Να pythonic. Χρησιμοποιήστε μια κατανόηση :

z={i:d[i] for d in [x,y] for i in d}

>>> print z
{'a': 1, 'c': 11, 'b': 10}
Απαντήθηκε 20/01/2016 στις 09:46
πηγή χρήστη

ψήφοι
6

(Για Python2.7 * μόνο? Υπάρχουν απλούστερες λύσεις για την python3 *).

Αν δεν είστε αντίθετος με την εισαγωγή ενός προτύπου ενότητα της βιβλιοθήκης, μπορείτε να κάνετε

from functools import reduce

def merge_dicts(*dicts):
    return reduce(lambda a, d: a.update(d) or a, dicts, {})

(Το or aκομμάτι στο lambdaείναι αναγκαία, διότι dict.updateπάντα επιστρέφει Noneστην επιτυχία.)

Απαντήθηκε 28/03/2016 στις 12:13
πηγή χρήστη

ψήφοι
4

Ξέρω ότι αυτό δεν ταιριάζει πραγματικά τις λεπτομέρειες των ερωτήσεων ( «μία επένδυση»), αλλά δεδομένου ότι καμία από τις απαντήσεις παραπάνω πήγε σε αυτή την κατεύθυνση, ενώ πολλές πολλές απαντήσεις ασχολήθηκε με το θέμα των επιδόσεων, ένιωσα ότι θα πρέπει να συμβάλει τις σκέψεις μου.

Ανάλογα με την περίπτωση χρήσης μπορεί να μην είναι απαραίτητο να δημιουργηθεί ένα «πραγματικό» νέα λεξικό των δεδομένων λεξικά εισόδου. Μια άποψη που κάνει αυτό θα μπορούσε να είναι επαρκής σε πολλές περιπτώσεις, δηλαδή ένα αντικείμενο το οποίο δρα σαν τη νέα λεξικό θα ήταν χωρίς τον υπολογισμό εντελώς. Ένας τεμπέλης έκδοση του συγχωνευμένου λεξικό, να το πω έτσι.

Στην Python, αυτό είναι μάλλον απλή και μπορεί να γίνει με τον κωδικό που εμφανίζεται στο τέλος του post μου. Αυτό το δεδομένο, η απάντηση στο αρχικό ερώτημα θα είναι:

z = MergeDict(x, y)

Όταν χρησιμοποιείτε αυτό το νέο αντικείμενο, θα συμπεριφέρεται σαν μια νέα λεξικό, αλλά θα έχει σταθερό χρόνο δημιουργίας και σταθερή αποτύπωμα μνήμης αφήνοντας τα πρωτότυπα λεξικά ανέγγιχτη. Η δημιουργία είναι τρόπος φθηνότερα από ό, τι στις άλλες λύσεις που προτείνονται.

Φυσικά, αν χρησιμοποιείτε το αποτέλεσμα πολλά, τότε κάποια στιγμή θα φτάσει στο όριο όπου δημιουργώντας μια πραγματική νέα λεξικό θα ήταν η πιο γρήγορη λύση. Όπως είπα, αυτό εξαρτάται από την περίπτωση χρήσης σας.

Αν έχετε νιώσει ποτέ ότι θα προτιμούσαν να έχουν μια πραγματική συγχωνευθούν dict, τότε καλώντας dict(z)θα το παράγει (αλλά πολύ πιο δαπανηρή από τις άλλες λύσεις, φυσικά, έτσι αυτό είναι ακριβώς που αξίζει να αναφερθεί).

Μπορείτε επίσης να χρησιμοποιήσετε αυτή την κατηγορία για να κάνουν ένα είδος copy-on-write λεξικό:

a = { 'x': 3, 'y': 4 }
b = MergeDict(a)  # we merge just one dict
b['x'] = 5
print b  # will print {'x': 5, 'y': 4}
print a  # will print {'y': 4, 'x': 3}

Εδώ είναι η ευθεία-εμπρός κώδικα MergeDict:

class MergeDict(object):
  def __init__(self, *originals):
    self.originals = ({},) + originals[::-1]  # reversed

  def __getitem__(self, key):
    for original in self.originals:
      try:
        return original[key]
      except KeyError:
        pass
    raise KeyError(key)

  def __setitem__(self, key, value):
    self.originals[0][key] = value

  def __iter__(self):
    return iter(self.keys())

  def __repr__(self):
    return '%s(%s)' % (
      self.__class__.__name__,
      ', '.join(repr(original)
          for original in reversed(self.originals)))

  def __str__(self):
    return '{%s}' % ', '.join(
        '%r: %r' % i for i in self.iteritems())

  def iteritems(self):
    found = set()
    for original in self.originals:
      for k, v in original.iteritems():
        if k not in found:
          yield k, v
          found.add(k)

  def items(self):
    return list(self.iteritems())

  def keys(self):
    return list(k for k, _ in self.iteritems())

  def values(self):
    return list(v for _, v in self.iteritems())
Απαντήθηκε 18/05/2016 στις 14:57
πηγή χρήστη

ψήφοι
9

Για Python 2:

x = {'a':1, 'b': 2}
y = {'b':10, 'c': 11}
z = dict(x.items()+y.items())
print(z)

Για Python 3:

x = {'a':1, 'b': 2}
y = {'b':10, 'c': 11}
z = dict(x.items()|y.items())
print(z)

Δίνει εξόδου:{'a': 1, 'c': 11, 'b': 10}

Απαντήθηκε 31/08/2016 στις 12:53
πηγή χρήστη

ψήφοι
6

Στην Python 3.5, μπορείτε να χρησιμοποιήσετε αποσυμπίεσης **, προκειμένου να δημιουργήσουν νέο λεξικό. Αυτή η μέθοδος έχει καμία έχουν έδειξε στο παρελθόν απαντήσεις. Επίσης, είναι καλύτερο να χρησιμοποιήσετε {}αντί του dict(). Επειδή {}είναι ένας πύθωνας κυριολεκτική και dict()περιλαμβάνει μια κλήση συνάρτησης.

dict1 = {'a':1}
dict2 = {'b':2}
new_dict = {**dict1, **dict2}
>>>new_dict
{'a':1, 'a':2}
Απαντήθηκε 27/09/2016 στις 23:33
πηγή χρήστη

ψήφοι
6

Μπορείτε να χρησιμοποιήσετε toolz.merge([x, y])για αυτό.

Απαντήθηκε 18/11/2016 στις 10:53
πηγή χρήστη

ψήφοι
9

Σε python 3:

import collections
a = {1: 1, 2: 2}
b = {2: 3, 3: 4}
c = {3: 5}

r = dict(collections.ChainMap(a, b, c))
print(r)

Εξω:

{1: 1, 2: 2, 3: 4}

Έγγραφα: https://docs.python.org/3/library/collections.html#collections.ChainMap :

Απαντήθηκε 24/05/2017 στις 06:24
πηγή χρήστη

ψήφοι
1

Το ερώτημα είναι με ετικέτα python-3x, αλλά, λαμβάνοντας υπόψη ότι πρόκειται για μια σχετικά πρόσφατη προσθήκη και ότι η πιο ψήφισε, αποδεκτή απάντηση ασχολείται εκτενώς με διάλυμα Python 2.x, τολμώ να προσθέσω ένα ένα σκάφος της γραμμής που αντλεί από ένα ενοχλητικό χαρακτηριστικό της Python 2.x λίστα κατανόηση, ότι είναι το όνομα διαρροή ...

$ python2
Python 2.7.13 (default, Jan 19 2017, 14:48:08) 
[GCC 6.3.0 20170118] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> [z.update(d) for z in [{}] for d in (x, y)]
[None, None]
>>> z
{'a': 1, 'c': 11, 'b': 10}
>>> ...

Είμαι στην ευχάριστη θέση να πω ότι το παραπάνω δεν λειτουργεί πια σε οποιαδήποτε έκδοση της Python 3.

Απαντήθηκε 30/05/2017 στις 11:28
πηγή χρήστη

ψήφοι
2

Αν δεν σας πειράζει μετάλλαξή του x,

x.update(y) or x

Απλή, ευανάγνωστο, αποδοτικοί. Θα γνωρίζετε update() πάντα επιστρέφει None, η οποία είναι μια ψεύτικη αξία. Έτσι θα αξιολογήσει πάντα x.

Η μετάλλαξη μεθόδους στην πρότυπη βιβλιοθήκη, όπως update, επιστροφή Noneκατά συνθήκη, έτσι ώστε αυτό το τέχνασμα θα λειτουργήσει σε εκείνους πάρα πολύ.

Εάν χρησιμοποιείτε μια βιβλιοθήκη που δεν ακολουθεί αυτή τη σύμβαση, μπορείτε να χρησιμοποιήσετε μια οθόνη πλειάδα και το δείκτη για να κάνει μια ενιαία έκφραση, αντί της or, αλλά δεν είναι τόσο ευανάγνωστο.

(x.update(y), x)[-1]

Αν δεν έχετε xσε μια μεταβλητή ακόμα, μπορείτε να χρησιμοποιήσετε lambdaγια να κάνετε ένα τοπικό χωρίς τη χρήση δήλωση εκχώρησης. Αυτό ισοδυναμεί με τη χρήση lambdaως έκφραση let , η οποία είναι μια κοινή τεχνική στη λειτουργική γλώσσα, αλλά μάλλον unpythonic.

(lambda x: x.update(y) or x)({'a':1, 'b': 2})

Αν θέλετε ένα αντίγραφο, PEP 448 είναι το καλύτερο {**x, **y}. Αλλά αν αυτό δεν είναι διαθέσιμο, αφήστε τα έργα εδώ.

(lambda z: z.update(y) or z)(x.copy())
Απαντήθηκε 22/09/2017 στις 01:57
πηγή χρήστη

ψήφοι
-3

x = { "a": 1}

y = { "b": 2}

x.update (y)

Εκτύπωση x # { 'a': 1, 'b': 2}

Απαντήθηκε 20/11/2017 στις 09:53
πηγή χρήστη

ψήφοι
-4
dictionaries = [{'body': 'text'},
{'correctAnswer': 'text'},
{'ans': 'text'},
{'ans': 'text'}]

final_dictionary = {}
for dictionary in dictionaries:
    for key in dictionary:
        final_dictionary[key] = dictionary[key]

print(final_dictionary)

Ακούγεται σαν να είναι πολύ νέα για να Python, έτσι ώστε η λύση που θα πρότεινα είναι το ένα πάνω από το οποίο νομίζω ότι είναι πιο ευανάγνωστο σε κάποιον που ξέρει μόνο για-βρόχους, και την επανάληψη τα κλειδιά ενός λεξικού. Ο ψευδο-κώδικας έχει ως εξής:

for each of the dictionaries in the list: 
    add each of the key-value pairs in that dictionary to our final dictionary.
Απαντήθηκε 04/12/2017 στις 20:56
πηγή χρήστη

ψήφοι
1

αποσπάσματος κώδικα - τελευταία

Python 3.6. *

d1 = {"a":1,"b":2,"c":3}
d2 = {"d":4,"e":5,"f":6}
d3 = {"g":7,"h":8,"j":9}
d4 = {'wtf':'yes'}

d1a = {"a":1,"b":2,"c":3}
d1b = {"a":2,"b":3,"c":4}
d1c = {"a":3,"b":4,"c":5}
d1d = {"a":"wtf"}

def dics_combine(*dics):
    dic_out = {}
    for d in dics:
        if isinstance(d, dict):
            dic_out = {**dic_out, **d}
        else:
            pass
    return dic_out

inp = (d1,d2,d3,d4)
combined_dics = dics_combine(*inp)
print('\n')
print('IN-ORDER: {0}'.format(inp))
print('OUT: {0}'.format(combined_dics))

inp = (d1a,d1b,d1c,d1d)
combined_dics = dics_combine(*inp)
print('\n')
print('IN-ORDER: {0}'.format(inp))
print('OUT: {0}'.format(combined_dics))

inp = (d1d,d1c,d1b,d1a)
combined_dics = dics_combine(*inp)
print('\n')
print('IN-ORDER: {0}'.format(inp))
print('OUT: {0}'.format(combined_dics)))

IN-ΔΙΑΤΑΞΗ: ({ 'a': 1, 'b': 2, 'c': 3}, { 'd': 4, 'e': 5, 'f': 6}, { 'g': 7, 'h': 8, 'j': 9}, { 'WTF': 'ναι'})

OUT: { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7, 'h': 8 'j': 9, 'στο διάολο': 'ναι'}

IN-ΔΙΑΤΑΞΗ: ({ 'a': 1, 'b': 2, 'c': 3}, { 'a': 2, 'b': 3, 'c': 4}, { 'a': 3, 'b': 4, 'c': 5}, { 'a': 'WTF'})

OUT: { 'a': 'WTF', 'β': 4, 'c': 5}

IN-ΔΙΑΤΑΞΗ: ({ 'a': 'WTF'}, { 'a': 3, 'b': 4, 'c': 5}, { 'a': 2, 'b': 3, «γ ': 4}, {' a ': 1, 'b': 2, 'c': 3})

OUT: { 'a': 1, 'b': 2, 'c': 3}

Απαντήθηκε 07/02/2018 στις 20:05
πηγή χρήστη

ψήφοι
0

Ήμουν περίεργος αν θα μπορούσα να κερδίσει χρόνο η αποδεκτή απάντηση με μια μια γραμμή stringify προσέγγιση:

Προσπάθησα 5 μεθόδους, κανένα προαναφέρθηκε - όλα μια επένδυση - όλα τα παράγουν σωστές απαντήσεις - και δεν θα μπορούσε να έρθει κοντά.

Έτσι ... να σας γλιτώσει από τον κόπο και ίσως να πληρούν περιέργεια:

import json
import yaml
import time
from ast import literal_eval as literal

def merge_two_dicts(x, y):
    z = x.copy()   # start with x's keys and values
    z.update(y)    # modifies z with y's keys and values & returns None
    return z

x = {'a':1, 'b': 2}
y = {'b':10, 'c': 11}

start = time.time()
for i in range(10000):
    z = yaml.load((str(x)+str(y)).replace('}{',', '))
elapsed = (time.time()-start)
print (elapsed, z, 'stringify yaml')

start = time.time()
for i in range(10000):
    z = literal((str(x)+str(y)).replace('}{',', '))
elapsed = (time.time()-start)
print (elapsed, z, 'stringify literal')

start = time.time()
for i in range(10000):
    z = eval((str(x)+str(y)).replace('}{',', '))
elapsed = (time.time()-start)
print (elapsed, z, 'stringify eval')

start = time.time()
for i in range(10000):
    z = {k:int(v) for k,v in (dict(zip(
            ((str(x)+str(y))
            .replace('}',' ')
            .replace('{',' ')
            .replace(':',' ')
            .replace(',',' ')
            .replace("'",'')
            .strip()
            .split('  '))[::2], 
            ((str(x)+str(y))
            .replace('}',' ')
            .replace('{',' ').replace(':',' ')
            .replace(',',' ')
            .replace("'",'')
            .strip()
            .split('  '))[1::2]
             ))).items()}
elapsed = (time.time()-start)
print (elapsed, z, 'stringify replace')

start = time.time()
for i in range(10000):
    z = json.loads(str((str(x)+str(y)).replace('}{',', ').replace("'",'"')))
elapsed = (time.time()-start)
print (elapsed, z, 'stringify json')

start = time.time()
for i in range(10000):
    z = merge_two_dicts(x, y)
elapsed = (time.time()-start)
print (elapsed, z, 'accepted')

Αποτελέσματα:

7.693928956985474 {'c': 11, 'b': 10, 'a': 1} stringify yaml
0.29134678840637207 {'c': 11, 'b': 10, 'a': 1} stringify literal
0.2208399772644043 {'c': 11, 'b': 10, 'a': 1} stringify eval
0.1106564998626709 {'c': 11, 'b': 10, 'a': 1} stringify replace
0.07989692687988281 {'c': 11, 'b': 10, 'a': 1} stringify json
0.005082368850708008 {'c': 11, 'b': 10, 'a': 1} accepted

Αυτό που έκανα μάθουμε από αυτό είναι ότι jsonη προσέγγιση είναι ο γρηγορότερος τρόπος (από αυτούς επιχείρησαν) για να επιστρέψει ένα λεξικό από κορδόνι-of-λεξικό? πολύ πιο γρήγορα (περίπου 1/4 του χρόνου) από ό, τι θεωρείται ότι είναι η συνήθης μέθοδος που χρησιμοποιούν ast. Έμαθα επίσης ότι, η yamlπροσέγγιση θα πρέπει να αποφευχθεί με κάθε κόστος.

Ναι, έχω πάρει ότι αυτή δεν είναι η καλύτερη / σωστός τρόπος γι 'αυτό παρακαλώ να μην downvote σε αρνητικό λήθη, το μηδέν είναι μια χαρά. Ήμουν περίεργος αν ήταν πιο γρήγορα, πράγμα που δεν είναι? I δημοσιεύτηκε για να το αποδείξει αυτό.

Απαντήθηκε 22/03/2018 στις 02:08
πηγή χρήστη

ψήφοι
0

Αυτή είναι μια έκφραση για Python 3.5 ή μεγαλύτερη που συγχωνεύει λεξικά χρησιμοποιώντας reduce:

>>> from functools import reduce
>>> l = [{'a': 1}, {'b': 2}, {'a': 100, 'c': 3}]
>>> reduce(lambda x, y: {**x, **y}, l, {})
{'a': 100, 'b': 2, 'c': 3}

Σημείωση: αυτό λειτουργεί ακόμη και αν το λεξικό λίστα είναι κενή ή περιέχει μόνο ένα στοιχείο.

Απαντήθηκε 15/04/2018 στις 22:02
πηγή χρήστη

ψήφοι
0

Πού είναι το πρόβλημα στον κώδικά σας;

Στην Python, λεξικό ορίζεται ως μια μη διατεταγμένη συλλογή από ζεύγη στοιχείων τιμή-κλειδί, όπου τα κλειδιά είναι μοναδικά και αμετάβλητα αντικείμενα.

Η update()μέθοδος ενημερώνει το αντικείμενο λεξικό κλήση, δηλαδή xμε το περιεχόμενο των διερχόμενων αντικειμένου λεξικό δηλαδή y.

Αν διαπιστώσει οποιαδήποτε διπλές κλειδί στο αντικείμενο καλώντας τότε θα αντικαταστήσει την αξία της με την αξία που αντιστοιχεί στο συμφωνημένα κλειδί που περνά αντικειμένου.

x = {'a':1, 'b': 2}
y = {'b':10, 'c': 11}

Έτσι θα πάρετε {'a': 1, 'b': 10, 'c': 11}στη θέση του να πάρει{'a': 1, 'b': 10, 'c': 11, 'b': 2}

Χρησιμοποιήστε λεξικό κατανόηση για την επίλυση

Το επαγγελματικό τρόπο για να δημιουργήσετε λεξικά χρησιμοποιώντας τα υπάρχοντα λεξικά ή άλλα αντικείμενα iterator.

>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>>
>>> my_dicts = (x, y);  # Gathering all dictionaries in a tuple/list
>>> z = {key: value for my_dict in my_dicts for key, value in my_dict.iteritems()}; # Single line of code that creates new dictionary object from existing dictionaries
>>> z
{'a': 1, 'c': 11, 'b': 10}

βιβλιογραφικές αναφορές

https://www.datacamp.com/community/tutorials/python-dictionary-comprehension

Ευχαριστώ.

Απαντήθηκε 07/05/2018 στις 05:53
πηγή χρήστη

ψήφοι
0

Νομίζω ότι άσχημο μονοκονδυλιές μου είναι μόνο απαραίτητη εδώ.

z = next(z.update(y) or z for z in [x.copy()])
# or
z = (lambda z: z.update(y) or z)(x.copy())
  1. Οι DICTS συγχωνεύονται.
  2. Ενιαία έκφραση.
  3. Μην ποτέ τολμήσει να το χρησιμοποιήσετε.
Απαντήθηκε 11/05/2018 στις 09:00
πηγή χρήστη

ψήφοι
4

Σε python2

dict(mydict, **other)

ή

In [11]: dict({1:2}.items() + {2:3}.items() + {1:5}.items() )
Out[11]: {1: 5, 2: 3}

python3

{ **mydict, **otherdict}
Απαντήθηκε 28/06/2018 στις 11:33
πηγή χρήστη

ψήφοι
1

Θα υπάρξει μια νέα επιλογή, όταν Python 3.8 κυκλοφορίες ( έχει προγραμματιστεί για τις 20 του Οκτώβρη, 2019 ), χάρη στην PEP 572: Εκφράσεις ανάθεσης . Ο νέος φορέας έκφρασης αποστολή :=σας επιτρέπει να ορίσετε το αποτέλεσμα του copyκαι εξακολουθεί να το χρησιμοποιήσετε για να καλέσετε update, αφήνοντας τον κωδικό της συνδυασμένης μια ενιαία έκφραση, αντί για δύο καταστάσεις, αλλάζοντας:

newdict = dict1.copy()
newdict.update(dict2)

προς το:

(newdict := dict1.copy()).update(dict2)

ενώ συμπεριφέρονται με τον ίδιο τρόπο με κάθε τρόπο. Εάν πρέπει να επιστρέψει η προκύπτουσα dict(που ζήτησε για μια έκφραση που επιστρέφουν το dict? Τα παραπάνω δημιουργεί και αναθέτει newdict, αλλά δεν θα επιστρέψει, έτσι δεν θα μπορούσε να το χρησιμοποιήσει για να περάσει ένα επιχείρημα σε μια συνάρτηση ως έχει, a la myfunc((newdict := dict1.copy()).update(dict2))) , τότε απλά προσθέστε or newdictστο τέλος (αφού updateεπιστρέφει None, η οποία είναι falsy, τότε θα αξιολογήσει και να επιστρέψει newdictως αποτέλεσμα της έκφρασης):

(newdict := dict1.copy()).update(dict2) or newdict

Σημαντική προειδοποίηση: Σε γενικές γραμμές, θα αποθαρρύνουν την προσέγγιση αυτή υπέρ του:

newdict = {**dict1, **dict2}

Η αποσυσκευασία προσέγγιση είναι πιο σαφής (για όποιον ξέρει για γενικευμένη αποσυσκευασία στην πρώτη θέση, η οποία θα πρέπει να ), δεν απαιτεί ένα όνομα για το αποτέλεσμα καθόλου (και έτσι είναι πολύ πιο περιεκτική κατά την κατασκευή μια προσωρινή ότι αμέσως πέρασε σε ένα λειτουργία ή περιλαμβάνονται σε list/ tupleκυριολεκτική ή κάτι παρόμοιο), και είναι σχεδόν σίγουρα πιο γρήγορα, καθώς, όντας (για CPython) περίπου ισοδύναμο με:

newdict = {}
newdict.update(dict1)
newdict.update(dict2)

αλλά γίνεται στο στρώμα C, χρησιμοποιώντας το σκυρόδεμα dictAPI, οπότε δεν συμβούλευσης δυναμική μέθοδο / πρόσδεσης ή κλήση συνάρτησης εναέρια αποστολή εμπλέκεται (όπου (newdict := dict1.copy()).update(dict2)είναι αναπόφευκτα πανομοιότυπο με το αρχικό δύο-επένδυση στη συμπεριφορά, που εκτελεί την εργασία σε διακριτά βήματα, με τη δυναμική αναζήτηση / πρόσδεσης / επίκληση των μεθόδων.

Είναι επίσης πιο επεκτάσιμη, η συγχώνευση τριών dicts είναι προφανής:

 newdict = {**dict1, **dict2, **dict3}

όπου χρησιμοποιώντας εκφράσεις ανάθεσης δεν θα κλίμακα έτσι? το πιο κοντινό θα μπορούσατε να πάρετε θα είναι:

 (newdict := dict1.copy()).update(dict2), newdict.update(dict3)

ή χωρίς την προσωρινή πλειάδα των Nones, αλλά με δοκιμές truthiness κάθε Noneαποτέλεσμα:

 (newdict := dict1.copy()).update(dict2) or newdict.update(dict3)

οποιαδήποτε από τις οποίες είναι προφανώς πολύ πιο άσχημο, και περιλαμβάνει περαιτέρω ανεπάρκειες (είτε μια χαμένη προσωρινή tupleτου Nones για διαχωρισμό κόμμα, ή άσκοπη δοκιμή truthiness κάθε update«s Noneαντάλλαγμα για orδιαχωρισμό).

Το μόνο πραγματικό πλεονέκτημα στην προσέγγιση της έκφρασης ανάθεση προκύπτει, εάν:

  1. Έχετε γενικό κώδικα που πρέπει να χειριστεί και τα δύο sets και dicts (και τα δύο στηρίζουν copyκαι update, έτσι ο κώδικας λειτουργεί περίπου όπως θα είναι να περιμένουμε)
  2. Μπορείτε να περιμένετε να λάβετε αυθαίρετες dict-όπως αντικείμενα , όχι μόνο dictη ίδια, και θα πρέπει να διατηρηθεί το είδος και τη σημασιολογία της αριστερή πλευρά (αντί να καταλήξουμε με ένα απλό dict). Ενώ myspecialdict({**speciala, **specialb})θα μπορούσε να λειτουργήσει, θα περιλαμβάνει ένα επιπλέον προσωρινή dict, και αν myspecialdictέχει χαρακτηριστικά απλά dictδεν μπορεί να διατηρήσει (π.χ. τακτική dicts διατηρήσει τώρα ώστε με βάση την πρώτη εμφάνιση ενός κλειδιού, και την αξία με βάση την τελευταία εμφάνιση ενός πλήκτρου? Μπορεί να θέλετε μία που διατηρεί ώστε με βάση την τελευταία εμφάνιση ενός κλειδιού έτσι την ενημέρωση μια τιμή δεν κινείται επίσης προς το τέλος), τότε η σημασιολογία θα ήταν λάθος. Δεδομένου ότι η έκδοση έκφραση ανάθεση χρησιμοποιεί τις όνομά μεθόδους (οι οποίες προφανώς υπερφορτωμένο να συμπεριφέρονται σωστά), δημιουργεί ποτέ dictσε όλα (εκτός και αν dict1ήταν ήδη dict), διατηρώντας την αρχική έγκριση τύπου (και τη σημασιολογία αρχικό τύπο του), όλα αποφεύγοντας οποιεσδήποτε προσωρινές αποκαταστάσεις.
Απαντήθηκε 28/02/2019 στις 15:16
πηγή χρήστη

ψήφοι
0

Θα έλεγα ότι θα πρέπει να κάνετε τα εξής:

z = dict(x.items() + y.items())
Απαντήθηκε 19/03/2019 στις 04:40
πηγή χρήστη

ψήφοι
0

μια γρήγορη λύση θα ήταν:

z4 = x.copy().update(y)
Απαντήθηκε 26/03/2019 στις 10:03
πηγή χρήστη

ψήφοι
0

Για Python 3:

from collections import ChainMap
a = {"a": 1, "b":2}
b = {"c":5, "d":8}
dict(ChainMap(a,b))  # {"a":1, "b":2, "c":5, "d":8}

Αν έχετε ίδιο κλειδί και στα δύο λεξικά, ChanMap θα χρησιμοποιήσει την αξία του πρώτου κλειδιού και αγνοεί την αξία του δεύτερου κλειδιού. Στην υγειά σας!

Απαντήθηκε 31/05/2019 στις 19:10
πηγή χρήστη

ψήφοι
0

Μπορείτε να χρησιμοποιήσετε μια λειτουργία για να γίνει αυτό:

def append(d1, d2):
    d1.update(d2)
    return d1

x = {'a':1, 'b': 2}
y = {'b':10, 'c': 11}
z = append(x, y)
print(z) #{'a': 1, 'b': 10, 'c': 11}
Απαντήθηκε 19/07/2019 στις 22:44
πηγή χρήστη

ψήφοι
0
 d1 = {'a': 10, 'b': 20}
 d2 = {'c': 30, 'd': 40, 'b': 50}
 l = d1.copy()
 s.update(d2)
 print(s)

παραγωγή:

{'a': 10, 'b': 50, 'c': 30, 'd': 4
Απαντήθηκε 14/09/2019 στις 18:33
πηγή χρήστη

ψήφοι
0

Μερικοί τρόποι για να το λύσει χωρίς τη χρήση ενότητες python (χωρίς εξαρτήσεις) με λίγες γραμμές των κωδικών.

Εκδόσεις ΟΛΑ Python (με λάμδα):

merge_dicts = lambda old, new: old.update(new) or old

Python Έκδοση> = 3.5:

def merge_dicts(old, new):
    return {**old, **new} 

Παλαιότερα Python Έκδοση:

def merge_dicts(old, new):
    merged = old.copy()
    merged.update(new)
    return merged

Αυτό το παράδειγμα θα συγχωνεύσει παλαιών και νέων, ενώ τη διαγραφή παλαιών αξιών με τις νέες τιμές.

ΧΡΗΣΗ:

old = {'name': 'Kevin', 'phone_number': '+33 12 34 45 67'}
new = {'name': 'Kevin', 'phone_number': '+33 88 88 88 88'}

print(merge_dicts(old, new))

ΠΑΡΑΓΩΓΗ:

{'name': 'Kevin', 'phone_number': '+33 88 88 88 88'}

Εάν έχετε να ασχοληθεί με πολλαπλάσια συγχωνεύθηκε από την παλιά στη νέα έκδοση, χωρίς να χάσει όλα τα δεδομένα ένα παράδειγμα προσέγγιση κάτω, χρησιμοποιώντας μια σειρά λεξικών:

ΟΛΑ Python Εκδόσεις:

def merge_dicts(old, news):
    merged = old.copy()
    for new in news:
        merged.update(new)
    return merged

ΧΡΗΣΗ:

old = {'name': 'Kevin', 'phone_number': '+33 12 34 45 67'}
new_01 = {'name': 'Kevin', 'phone_number': '+33 77 77 77 77', 'age': 28}
new_02 = {'name': 'SabK', 'phone_number': '+33 88 88 88 89'}
new_03 = {'phone_number': '+33 99 99 99 99'}

print(merge_dicts(old, [new_01, new_02, new_03]))

ΠΑΡΑΓΩΓΗ:

{'phone_number': '+33 99 99 99 99', 'age': 28, 'name': 'SabK'}

Σε αυτό το παράδειγμα, το νέο λεξικό θα δημιουργηθεί από την παλιά (πρώτο επιχείρημα) και, στη συνέχεια, θα ενημερώσει διαδοχικά από το πρώτο στοιχείο του πίνακα στο τελευταίο (new_01> new_02> new_03)

Στο τέλος, θα πάρει όλα τα datas από όλα λεξικό θα αναπροσαρμόζοντας τις αντικειμενικές αξίες που όπως ήταν η αλλαγή. Αυτή η λειτουργία μπορεί να είναι πραγματικά χρήσιμο όταν έχετε ασχοληθεί με datas που αλλάζουν συχνά.

Απαντήθηκε 06/12/2019 στις 23:46
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more