Python dict обновляет разность

case val of case1

не делает то, что, по вашему мнению, делает, а именно проверяет, равен ли val case1. Он вводит новую привязку с именем case1, скрывая существующую привязку, значение которой равно val. Вы не получаете сравнения на равенство бесплатно: вы должны запросить их, используя ==, возможно, в предложении guard или в выражении if. Итак, у вас есть два избыточных шаблона: предложение _ никогда не будет введено, потому что шаблон case1 соответствует всем возможным входам.

Вместо этого, напишите тест на равенство самостоятельно. Есть более хорошие способы сделать это, но способ сделать это, внося минимальные изменения в вашу существующую функцию, может быть:

... do
  val <- evaluate var memory
  if val == case1
    then interpret ...
    else interpret ...
6
задан adam 3 April 2009 в 19:28
поделиться

6 ответов

Нет, но можно разделить dict на подклассы для обеспечения уведомления на изменении.

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 )

Обратите внимание, что суперкласс Наблюдатель определил, здесь не проверяет, чтобы видеть, было ли "реальное" изменение или нет; это просто отмечает, что было изменение.

10
ответ дан 8 December 2019 в 04:55
поделиться

Нет, это не делает. Но не трудно записать функцию разности словаря:

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
2
ответ дан 8 December 2019 в 04:55
поделиться

Простую функцию diffing легко записать. В зависимости от того, как часто Вам нужен он, это может быть быстрее, чем более изящный ObservableDict 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 })
2
ответ дан 8 December 2019 в 04:55
поделиться
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'}
1
ответ дан 8 December 2019 в 04:55
поделиться

Не встроенный, но Вы могли выполнить итерации на ключах dict и сделать сравнения. Могло быть медленным все же.

Лучшее решение состоит в том, чтобы, вероятно, создать более сложный datastructure и использовать словарь в качестве базового представления.

0
ответ дан 8 December 2019 в 04:55
поделиться

год спустя

Мне нравится следующее решение:

>>> 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'}
9
ответ дан 8 December 2019 в 04:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: