6 Stimmen

python dict update diff

Hat Python irgendeine Art von eingebauter Funktionalität, um mitzuteilen, welche Wörterbuchelemente sich bei einer Diktataktualisierung geändert haben? Zum Beispiel bin ich für einige Funktionalität wie diese suchen:

>>> a = {'a':'hamburger', 'b':'fries', 'c':'coke'}
>>> b = {'b':'fries', 'c':'pepsi', 'd':'ice cream'}
>>> a.diff(b)
{'c':'pepsi', 'd':'ice cream'}
>>> a.update(b)
>>> a
{'a':'hamburger', 'b':'fries', 'c':'pepsi', 'd':'ice cream'}

Ich möchte ein Wörterbuch der geänderten Werte erhalten, wie sie im Ergebnis von a.diff(b) angezeigt werden

11voto

S.Lott Punkte 371691

Nein, aber Sie können dict unterordnen, um eine Benachrichtigung bei Änderungen zu erhalten.

class ObservableDict( dict ):
    def __init__( self, *args, **kw ):
        self.observers= []
        super( ObservableDict, self ).__init__( *args, **kw )
    def observe( self, observer ):
        self.observers.append( observer )
    def __setitem__( self, key, value ):
        for o in self.observers:
            o.notify( self, key, self[key], value )
        super( ObservableDict, self ).__setitem__( key, value )
    def update( self, anotherDict ):
        for k in anotherDict:
            self[k]= anotherDict[k]

class Watcher( object ):
    def notify( self, observable, key, old, new ):
        print "Change to ", observable, "at", key

w= Watcher()
a= ObservableDict( {'a':'hamburger', 'b':'fries', 'c':'coke'} )
a.observe( w )
b = {'b':'fries', 'c':'pepsi'}
a.update( b )

Beachten Sie, dass die hier definierte Oberklasse Watcher nicht prüft, ob es eine "echte" Änderung gab oder nicht; sie stellt lediglich fest, dass es eine Änderung gab.

9voto

remosu Punkte 4959

Ein Jahr später

Mir gefällt die folgende Lösung:

>>> def dictdiff(d1, d2):                                              
        return dict(set(d2.iteritems()) - set(d1.iteritems()))
... 
>>> a = {'a':'hamburger', 'b':'fries', 'c':'coke'}
>>> b = {'b':'fries', 'c':'pepsi', 'd':'ice cream'}
>>> dictdiff(a, b)
{'c': 'pepsi', 'd': 'ice cream'}

2voto

Can Berk Güder Punkte 103655

Nein, das tut es nicht. Aber es ist nicht schwer, eine Wörterbuch-Diff-Funktion zu schreiben:

def diff(a, b):
  diff = {}
  for key in b.keys():
    if (not a.has_key(key)) or (a.has_key(key) and a[key] != b[key]):
      diff[key] = b[key]
  return diff

2voto

Eine einfache Diffing-Funktion ist leicht zu schreiben. Je nachdem, wie oft man sie braucht, kann sie schneller sein als das elegantere ObservableDict von S. Lott.

def dict_diff(a, b):
    """Return differences from dictionaries a to b.

    Return a tuple of three dicts: (removed, added, changed).
    'removed' has all keys and values removed from a. 'added' has
    all keys and values that were added to b. 'changed' has all
    keys and their values in b that are different from the corresponding
    key in a.

    """

    removed = dict()
    added = dict()
    changed = dict()

    for key, value in a.iteritems():
        if key not in b:
            removed[key] = value
        elif b[key] != value:
            changed[key] = b[key]
    for key, value in b.iteritems():
        if key not in a:
            added[key] = value
    return removed, added, changed

if __name__ == "__main__":
    print dict_diff({'foo': 1, 'bar': 2, 'yo': 4 }, 
                    {'foo': 0, 'foobar': 3, 'yo': 4 })

1voto

AKX Punkte 121150
def diff_update(dict_to_update, updater):
    changes=dict((k,updater[k]) for k in filter(lambda k:(k not in dict_to_update or updater[k] != dict_to_update[k]), updater.iterkeys()))
    dict_to_update.update(updater)
    return changes

a = {'a':'hamburger', 'b':'fries', 'c':'coke'}
b = {'b':'fries', 'c':'pepsi'}
>>> print diff_update(a, b)
{'c': 'pepsi'}
>>> print a
{'a': 'hamburger', 'c': 'pepsi', 'b': 'fries'}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X