case val of case1
не делает то, что, по вашему мнению, делает, а именно проверяет, равен ли val case1. Он вводит новую привязку с именем case1, скрывая существующую привязку, значение которой равно val. Вы не получаете сравнения на равенство бесплатно: вы должны запросить их, используя ==
, возможно, в предложении guard или в выражении if
. Итак, у вас есть два избыточных шаблона: предложение _
никогда не будет введено, потому что шаблон case1
соответствует всем возможным входам.
Вместо этого, напишите тест на равенство самостоятельно. Есть более хорошие способы сделать это, но способ сделать это, внося минимальные изменения в вашу существующую функцию, может быть:
... do
val <- evaluate var memory
if val == case1
then interpret ...
else interpret ...
Нет, но можно разделить 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 )
Обратите внимание, что суперкласс Наблюдатель определил, здесь не проверяет, чтобы видеть, было ли "реальное" изменение или нет; это просто отмечает, что было изменение.
Нет, это не делает. Но не трудно записать функцию разности словаря:
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
Простую функцию 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 })
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'}
Не встроенный, но Вы могли выполнить итерации на ключах dict и сделать сравнения. Могло быть медленным все же.
Лучшее решение состоит в том, чтобы, вероятно, создать более сложный datastructure и использовать словарь в качестве базового представления.
Мне нравится следующее решение:
>>> 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'}