ATLAS Offline Software
StackedDict.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
2 
3 #
4 # @file D3PDMakerCoreComps/python/StackedDict.py
5 # @author scott snyder <snyder@bnl.gov>
6 # @date Nov, 2012
7 # @brief Allow lookups in multiple dictionaries while writing to one.
8 #
9 
10 
11 import collections.abc
12 
13 
14 class StackedDict (collections.abc.Mapping):
15  """Allow lookups in multiple dictionaries while writing to one.
16 
17  A StackedDict references a list of other dictionaries.
18  Reads try each dictionary in sequence, succeeding with the first dictionary
19  that contains the target key. Modifications go to the last dictionary
20  in the list.
21 
22  Notes: No attempt is made to deal with keys duplicated between dictionaries;
23  len() and __iter__ will process them all. __delitem__ is not implemented.
24 
25  Examples:
26  >>> from pprint import pprint
27  >>> d1 = {'a':'b'}
28  >>> d2 = {'c':'d'}
29  >>> d3 = {'e':'f'}
30  >>> d = StackedDict (d1, d2, d3)
31  >>> d['a']
32  'b'
33  >>> d['c']
34  'd'
35  >>> d['e']
36  'f'
37  >>> len(d)
38  3
39  >>> [x for x in d]
40  ['a', 'c', 'e']
41  >>> 'c' in d
42  True
43  >>> 'c' in d
44  True
45  >>> 'd' in d
46  False
47  >>> d['c'] = 10
48  >>> d['c']
49  10
50  >>> d2
51  {'c': 10}
52  >>> d['x'] = 20
53  >>> d['x']
54  20
55  >>> pprint(d3)
56  {'e': 'f', 'x': 20}
57  >>> pprint(d.copy())
58  {'a': 'b', 'c': 10, 'e': 'f', 'x': 20}
59 """
60 
61  def __init__ (self, *dicts):
62  self.dicts = dicts
63  return
64 
65 
66  def __getitem__ (self, k):
67  for d in self.dicts:
68  if k in d:
69  return d[k]
70  raise KeyError (k)
71 
72 
73  def __setitem__ (self, k, v):
74  for d in self.dicts[:-1]:
75  if k in d:
76  d[k] = v
77  return
78  self.dicts[-1][k] = v
79  return
80 
81 
82  def __len__ (self):
83  return sum([len(d) for d in self.dicts])
84 
85 
86  def __iter__ (self):
87  for d in self.dicts:
88  for x in d: yield x
89  return
90 
91 
92  def has_key (self, k):
93  """Some code still uses this.
94  >>> d1 = {'a':'b'}
95  >>> d = StackedDict (d1)
96  >>> d.has_key ('a')
97  True
98  >>> d.has_key ('z')
99  False
100  """
101  return k in self
102 
103 
104  def copy (self):
105  d = {}
106  for i in range(len(self.dicts)-1, -1, -1):
107  d.update(self.dicts[i])
108  return d
109 
python.StackedDict.StackedDict.__len__
def __len__(self)
Definition: StackedDict.py:82
python.StackedDict.StackedDict.__getitem__
def __getitem__(self, k)
Definition: StackedDict.py:66
convertTimingResiduals.sum
sum
Definition: convertTimingResiduals.py:55
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
python.StackedDict.StackedDict.copy
def copy(self)
Definition: StackedDict.py:104
python.StackedDict.StackedDict.dicts
dicts
Definition: StackedDict.py:62
python.StackedDict.StackedDict.has_key
def has_key(self, k)
Definition: StackedDict.py:92
python.StackedDict.StackedDict.__init__
def __init__(self, *dicts)
Definition: StackedDict.py:61
python.StackedDict.StackedDict.__iter__
def __iter__(self)
Definition: StackedDict.py:86
python.StackedDict.StackedDict
Definition: StackedDict.py:14
python.StackedDict.StackedDict.__setitem__
def __setitem__(self, k, v)
Definition: StackedDict.py:73