# Решение на BiDict от Явор Папазов

Обратно към всички решения

Към профила на Явор Папазов

## Резултати

• 6 точки от тестове
• 0 бонус точки
• 6 точки общо
• 15 успешни тест(а)
• 1 неуспешни тест(а)

## Код

class BiDict:
"""Class that is a dictionary in both directions:
Both keys and values are unique and reversing
the order of (key, value) is possible (it can
be seen as finding the inverse of a discrete
function).
Complexity guarantees:
reverse() is O(1).
Normal dict operations are of the same asymptotic
complexity as the original dict implementation.
Implementation note: this class does not inherit
from dict, since the Liskov substitution principle
would be violated"""
def __init__(self, dictionary=None):
if dictionary == None:
dictionary = {}
self._forward_dict = {}
self._rev_dict = {}
f_dict = self._forward_dict
r_dict = self._rev_dict
try:
for (k, v) in dictionary.items():
if v in r_dict:
del f_dict[r_dict[v]]
f_dict[k] = v
r_dict[v] = k
except AttributeError:
raise TypeError
def inverse(self):
new_f_dict = self._rev_dict
self._rev_dict = self._forward_dict
self._forward_dict = new_f_dict
def __len__(self):
return len(self._forward_dict)
def __eq__(self, other):
return self._forward_dict == other._forward_dict
def __ne__(self, other):
return self._forward_dict != other._forward_dict
def __repr__(self):
return "BiDict({0})".format(self._forward_dict.__repr__())
def __iter__(self):
return iter(self._forward_dict)
def __contains__(self, key):
return self._forward_dict.__contains__(key)
def __delitem__(self, key):
value = self._forward_dict[key]
del self._forward_dict[key]
del self._rev_dict[value]
def __getitem__(self, key):
return self._forward_dict[key]
def __setitem__(self, key, value):
f_dict = self._forward_dict
r_dict = self._rev_dict
if key in f_dict:
del r_dict[f_dict[key]] # fix
if value in r_dict:
del f_dict[r_dict[value]] # fix
f_dict[key] = value
r_dict[value] = key
def __reduce__(self):
raise TypeError("can't pickle %s objects" % self.__class__.__name__)
def __reduce_ex__(self):
raise TypeError("can't pickle %s objects" % self.__class__.__name__)
def clear(self):
self._forward_dict = {}
self._rev_dict = {}
def copy(self):
return BiDict(self._forward_dict)
def get(self, key):
return self.__getitem__(key)
def items(self):
return self._forward_dict.items()
def keys(self):
return self._forward_dict.keys()
def pop(self, key, default=None):
if default == None or self._forward_dict.__contains__(key):
val = self._forward_dict.pop(key)
del self._rev_dict[val]
return val
else:
return default
def popitem(self):
kv_pair = self._forward_dict.popitem()
del self._rev_dict[kv_pair[1]]
return kv_pair
def update(self, E=None, **F):
if E == None:
E = []
try:
e_keys = E.keys()
for k in E:
self.__setitem__(k, E[k])
except AttributeError:
for (k, v) in E:
self.__setitem__(k, v)
for k in F:
self.__setitem__(k, F[k])
def values(self):
return self._forward_dict.values()

## Лог от изпълнението

..E.............
======================================================================
ERROR: test_circular_values (__main__.BiDictTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test20120627-22085-1fco2fx", line 49, in test_circular_values
circular = self.solutions.BiDict({1: 2, 2: 3, 3: 1})
AttributeError: 'BiDictTestCase' object has no attribute 'solutions'

----------------------------------------------------------------------
Ran 16 tests in 0.002s

FAILED (errors=1)

## История (1 версия и 0 коментара)

### Явор обнови решението на 11.04.2012 15:54 (преди над 12 години)

+class BiDict:
+
+ """Class that is a dictionary in both directions:
+ Both keys and values are unique and reversing
+ the order of (key, value) is possible (it can
+ be seen as finding the inverse of a discrete
+ function).
+ Complexity guarantees:
+ reverse() is O(1).
+ Normal dict operations are of the same asymptotic
+ complexity as the original dict implementation.
+ Implementation note: this class does not inherit
+ from dict, since the Liskov substitution principle
+ would be violated"""
+
+ def __init__(self, dictionary=None):
+ if dictionary == None:
+ dictionary = {}
+ self._forward_dict = {}
+ self._rev_dict = {}
+ f_dict = self._forward_dict
+ r_dict = self._rev_dict
+ try:
+ for (k, v) in dictionary.items():
+ if v in r_dict:
+ del f_dict[r_dict[v]]
+ f_dict[k] = v
+ r_dict[v] = k
+ except AttributeError:
+ raise TypeError
+
+ def inverse(self):
+ new_f_dict = self._rev_dict
+ self._rev_dict = self._forward_dict
+ self._forward_dict = new_f_dict
+
+ def __len__(self):
+ return len(self._forward_dict)
+
+ def __eq__(self, other):
+ return self._forward_dict == other._forward_dict
+
+ def __ne__(self, other):
+ return self._forward_dict != other._forward_dict
+
+ def __repr__(self):
+ return "BiDict({0})".format(self._forward_dict.__repr__())
+
+ def __iter__(self):
+ return iter(self._forward_dict)
+
+ def __contains__(self, key):
+ return self._forward_dict.__contains__(key)
+
+ def __delitem__(self, key):
+ value = self._forward_dict[key]
+ del self._forward_dict[key]
+ del self._rev_dict[value]
+
+ def __getitem__(self, key):
+ return self._forward_dict[key]
+
+ def __setitem__(self, key, value):
+ f_dict = self._forward_dict
+ r_dict = self._rev_dict
+ if key in f_dict:
+ del r_dict[f_dict[key]] # fix
+ if value in r_dict:
+ del f_dict[r_dict[value]] # fix
+ f_dict[key] = value
+ r_dict[value] = key
+
+ def __reduce__(self):
+ raise TypeError("can't pickle %s objects" % self.__class__.__name__)
+
+ def __reduce_ex__(self):
+ raise TypeError("can't pickle %s objects" % self.__class__.__name__)
+
+ def clear(self):
+ self._forward_dict = {}
+ self._rev_dict = {}
+
+ def copy(self):
+ return BiDict(self._forward_dict)
+
+ def get(self, key):
+ return self.__getitem__(key)
+
+ def items(self):
+ return self._forward_dict.items()
+
+ def keys(self):
+ return self._forward_dict.keys()
+
+ def pop(self, key, default=None):
+ if default == None or self._forward_dict.__contains__(key):
+ val = self._forward_dict.pop(key)
+ del self._rev_dict[val]
+ return val
+ else:
+ return default
+
+ def popitem(self):
+ kv_pair = self._forward_dict.popitem()
+ del self._rev_dict[kv_pair[1]]
+ return kv_pair
+
+ def update(self, E=None, **F):
+ if E == None:
+ E = []
+ try:
+ e_keys = E.keys()
+ for k in E:
+ self.__setitem__(k, E[k])
+ except AttributeError:
+ for (k, v) in E:
+ self.__setitem__(k, v)
+ for k in F:
+ self.__setitem__(k, F[k])
+
+ def values(self):
+ return self._forward_dict.values()