from torch_snippets import AD
AttrDict / AD
+Basic Invocations
+Just replace dict
with AD
+AD is simply a dictionary, so you can create one in the same way you would create any dictionary.
+= AD(x='1', y=2.0, z=3+5j, k=AD(l={'you':'can','nest':'dictionaries'}, m=2, n=3))
+ ad print(ad)
+```↯ AttrDict ↯
+x - 1 (🏷️ str)
+y - 2.0 (🏷️ float)
+z - (3+5j) (🏷️ complex)
+k
+ l
+ you - can (🏷️ str)
+ nest - dictionaries (🏷️ str)
+ m - 2 (🏷️ int)
+ n - 3 (🏷️ int)
+
+```
+
+AD supports args
+AD(x,y,z) == AD(x=x, y=y, z=z)
+If you want to create a dictionary from variables, there’s a good chance that the key you’d want to assign to that variable is the same as your variable name. AttrDict introspects the args intelligently (thanks to icecream module) and assigns the variable itself as the key name
='1',2.0,3+5j
+ x,y,z={'y':{'c':{'n':'d','greet':'hello','o':[1,2,3,{'m':{'n':[4,5,6]}}]}}},2,3
+ l,m,n= AD(l,m,n)
+ k = AD(x,y,z,k)
+ ad print(ad)
+```↯ AttrDict ↯
+x - 1 (🏷️ str)
+y - 2.0 (🏷️ float)
+z - (3+5j) (🏷️ complex)
+k
+ l
+ y
+ c
+ n - d (🏷️ str)
+ greet - hello (🏷️ str)
+ o[]
+ 0 - 1 (🏷️ int)
+ 1 - 2 (🏷️ int)
+ 2 - 3 (🏷️ int)
+ 3
+ m
+ n[]
+ 0 - 4 (🏷️ int)
+ 1 - 5 (🏷️ int)
+ 2 - 6 (🏷️ int)
+ m - 2 (🏷️ int)
+ n - 3 (🏷️ int)
+
+```
+
+Don’t worry if you want to control the key names, you can still give your own kwargs, or even mix it up with both args and kwargs
+= AD(l,m,n)
+ k = AD(x,y,zed=z,kay=k)
+ ad print(ad)
+```↯ AttrDict ↯
+x - 1 (🏷️ str)
+y - 2.0 (🏷️ float)
+zed - (3+5j) (🏷️ complex)
+kay
+ l
+ y
+ c
+ n - d (🏷️ str)
+ greet - hello (🏷️ str)
+ o[]
+ 0 - 1 (🏷️ int)
+ 1 - 2 (🏷️ int)
+ 2 - 3 (🏷️ int)
+ 3
+ m
+ n[]
+ 0 - 4 (🏷️ int)
+ 1 - 5 (🏷️ int)
+ 2 - 6 (🏷️ int)
+ m - 2 (🏷️ int)
+ n - 3 (🏷️ int)
+
+```
+
+Methods
+Since AD is an extension of a dictionary, all the dictionary methods such as .keys()
, .values()
, .items()
work exactly as expected
.keys
+ ad.keys()
dict_keys(['x', 'y', 'zed', 'kay'])
+.values
+ ad.values()
dict_values(['1', 2.0, (3+5j),
+```↯ AttrDict ↯
+l
+ y
+ c
+ n - d (🏷️ str)
+ greet - hello (🏷️ str)
+ o[]
+ 0 - 1 (🏷️ int)
+ 1 - 2 (🏷️ int)
+ 2 - 3 (🏷️ int)
+ 3
+ m
+ n[]
+ 0 - 4 (🏷️ int)
+ 1 - 5 (🏷️ int)
+ 2 - 6 (🏷️ int)
+m - 2 (🏷️ int)
+n - 3 (🏷️ int)
+
+```
+])
+.items
+ ad.items()
dict_items([('x', '1'), ('y', 2.0), ('zed', (3+5j)), ('kay',
+```↯ AttrDict ↯
+l
+ y
+ c
+ n - d (🏷️ str)
+ greet - hello (🏷️ str)
+ o[]
+ 0 - 1 (🏷️ int)
+ 1 - 2 (🏷️ int)
+ 2 - 3 (🏷️ int)
+ 3
+ m
+ n[]
+ 0 - 4 (🏷️ int)
+ 1 - 5 (🏷️ int)
+ 2 - 6 (🏷️ int)
+m - 2 (🏷️ int)
+n - 3 (🏷️ int)
+
+```
+)])
+Use .dict
to Create a Vanilla Dict
+= ad.dict()
+ d d
{'x': '1',
+ 'y': 2.0,
+ 'zed': (3+5j),
+ 'kay': {'l': {'y': {'c': {'n': 'd',
+ 'greet': 'hello',
+ 'o': [1, 2, 3, {'m': {'n': [4, 5, 6]}}]}}},
+ 'm': 2,
+ 'n': 3}}
+AD
From Vanilla Dict (Another Basic Invocation)
+= AD(d)
+ ad ad
+```↯ AttrDict ↯
+x - 1 (🏷️ str)
+y - 2.0 (🏷️ float)
+zed - (3+5j) (🏷️ complex)
+kay
+ l
+ y
+ c
+ n - d (🏷️ str)
+ greet - hello (🏷️ str)
+ o[]
+ 0 - 1 (🏷️ int)
+ 1 - 2 (🏷️ int)
+ 2 - 3 (🏷️ int)
+ 3
+ m
+ n[]
+ 0 - 4 (🏷️ int)
+ 1 - 5 (🏷️ int)
+ 2 - 6 (🏷️ int)
+ m - 2 (🏷️ int)
+ n - 3 (🏷️ int)
+
+```
+.
Accessing a key
+As the name of the class suggests, keys can be accessed as if they are attributes
+assert ad.x == d['x']
+assert ad.kay.l.y.c.n == d['kay']['l']['y']['c']['n']
+assert ad.kay.l.y.c.o[3].m.n == d['kay']['l']['y']['c']['o'][3]['m']['n']
in
Searching for keys
+Highlevel keys are anyway accessable just like, in a normal dictionary
+assert 'zed' in ad
you can check for presence/absence of nested keys by joining them with a ‘.’
+assert 'kay.l.y.c.n' in ad
.find_address
Find if a key exists and return where it is, i.e., the address of the key
+The method always returns a list of addresses
+'c') ad.find_address(
['kay.l.y.c']
+'n') ad.find_address(
['kay.l.y.c.n', 'kay.l.y.c.o.3.m.n', 'kay.n']
+'hello') ad.find_address(
[]
+.fetch
fetch all the addresses
+'n')) ad.fetch(ad.find_address(
(#3) ['d',[4, 5, 6],3]
+'kay.l.y.c.n', 'kay.l.y.c.o.3.m.n', 'kay.n']) ad.fetch([
(#3) ['d',[4, 5, 6],3]
+.fetch2
fetches all the addresses while preserving the key hierarchy
+=['kay.l.y.c.n', 'kay.l.y.c.o.3.m.n', 'kay.n']) ad.fetch2(addrs
+```↯ AttrDict ↯
+kay
+ l
+ y
+ c
+ n - d (🏷️ str)
+ o
+ 3
+ m
+ n[]
+ 0 - 4 (🏷️ int)
+ 1 - 5 (🏷️ int)
+ 2 - 6 (🏷️ int)
+ n - 3 (🏷️ int)
+
+```
+.fetch2
can also directly fetch all the keys at once (by first finding all addresses and then fetching all of them)
+='n') ad.fetch2(key
+```↯ AttrDict ↯
+kay
+ l
+ y
+ c
+ n - d (🏷️ str)
+ o
+ 3
+ m
+ n[]
+ 0 - 4 (🏷️ int)
+ 1 - 5 (🏷️ int)
+ 2 - 6 (🏷️ int)
+ n - 3 (🏷️ int)
+
+```
+.slice
make a dictionary out of all keys present anywhere in the dictionary
+slice('n') ad.
+```↯ AttrDict ↯
+kay.l.y.c.n - d (🏷️ str)
+kay.l.y.c.o.3.m.n[]
+ 0 - 4 (🏷️ int)
+ 1 - 5 (🏷️ int)
+ 2 - 6 (🏷️ int)
+kay.n - 3 (🏷️ int)
+
+```
+.get
+Get works as usual but can also work with nested keys
+'x',10) ad.get(
'1'
+'yolo',10) ad.get(
10
+'kay.l.y.c',20) ad.get(
+```↯ AttrDict ↯
+n - d (🏷️ str)
+greet - hello (🏷️ str)
+o[]
+ 0 - 1 (🏷️ int)
+ 1 - 2 (🏷️ int)
+ 2 - 3 (🏷️ int)
+ 3
+ m
+ n[]
+ 0 - 4 (🏷️ int)
+ 1 - 5 (🏷️ int)
+ 2 - 6 (🏷️ int)
+
+```
+'kay.l.y.hello',20) ad.get(
20
+.set
+Will also work similarly as get
+set('bee.sea.dee', 'e') ad.
ad
+```↯ AttrDict ↯
+x - 1 (🏷️ str)
+y - 2.0 (🏷️ float)
+zed - (3+5j) (🏷️ complex)
+kay
+ l
+ y
+ c
+ n - d (🏷️ str)
+ greet - hello (🏷️ str)
+ o[]
+ 0 - 1 (🏷️ int)
+ 1 - 2 (🏷️ int)
+ 2 - 3 (🏷️ int)
+ 3
+ m
+ n[]
+ 0 - 4 (🏷️ int)
+ 1 - 5 (🏷️ int)
+ 2 - 6 (🏷️ int)
+ m - 2 (🏷️ int)
+ n - 3 (🏷️ int)
+bee
+ sea
+ dee - e (🏷️ str)
+
+```
+.map
Map a function on all leaf nodes
+from torch_snippets import h4
+def into_two(x): return 2*x
+= ad.map(into_two)
+ ad2 "Original")
+ h4(print(ad)
+"New")
+ h4(print(ad2)
Original
+
+```↯ AttrDict ↯
+x - 1 (🏷️ str)
+y - 2.0 (🏷️ float)
+zed - (3+5j) (🏷️ complex)
+kay
+ l
+ y
+ c
+ n - d (🏷️ str)
+ greet - hello (🏷️ str)
+ o[]
+ 0 - 1 (🏷️ int)
+ 1 - 2 (🏷️ int)
+ 2 - 3 (🏷️ int)
+ 3
+ m
+ n[]
+ 0 - 4 (🏷️ int)
+ 1 - 5 (🏷️ int)
+ 2 - 6 (🏷️ int)
+ m - 2 (🏷️ int)
+ n - 3 (🏷️ int)
+bee
+ sea
+ dee - e (🏷️ str)
+
+```
+
+New
+
+```↯ AttrDict ↯
+x - 11 (🏷️ str)
+y - 4.0 (🏷️ float)
+zed - (6+10j) (🏷️ complex)
+kay
+ l
+ y
+ c
+ n - dd (🏷️ str)
+ greet - hellohello (🏷️ str)
+ o[]
+ 0 - 2 (🏷️ int)
+ 1 - 4 (🏷️ int)
+ 2 - 6 (🏷️ int)
+ 3
+ m
+ n[]
+ 0 - 8 (🏷️ int)
+ 1 - 10 (🏷️ int)
+ 2 - 12 (🏷️ int)
+ m - 4 (🏷️ int)
+ n - 6 (🏷️ int)
+bee
+ sea
+ dee - ee (🏷️ str)
+
+```
+
+.trymap
Map a function on all leaf nodes and preserve the leaf as it is, if the function fails
+def plus_one(x): return x+1000
+= ad.trymap(plus_one)
+ ad2 print(ad2)
+```↯ AttrDict ↯
+x - 1 (🏷️ str)
+y - 1002.0 (🏷️ float)
+zed - (1003+5j) (🏷️ complex)
+kay
+ l
+ y
+ c
+ n - d (🏷️ str)
+ greet - hello (🏷️ str)
+ o[]
+ 0 - 1001 (🏷️ int)
+ 1 - 1002 (🏷️ int)
+ 2 - 1003 (🏷️ int)
+ 3
+ m
+ n[]
+ 0 - 1004 (🏷️ int)
+ 1 - 1005 (🏷️ int)
+ 2 - 1006 (🏷️ int)
+ m - 1002 (🏷️ int)
+ n - 1003 (🏷️ int)
+bee
+ sea
+ dee - e (🏷️ str)
+
+```
+
+.drop
Drop a key, even if it is present somewhere nested
+'n') ad.find_address(
['kay.l.y.c.n', 'kay.l.y.c.o.3.m.n', 'kay.n']
+from copy import deepcopy
+= deepcopy(ad)
+ ad2 'n') ad2.drop(
ad2
+```↯ AttrDict ↯
+x - 1 (🏷️ str)
+y - 2.0 (🏷️ float)
+zed - (3+5j) (🏷️ complex)
+kay
+ l
+ y
+ c
+ greet - hello (🏷️ str)
+ o[]
+ 0 - 1 (🏷️ int)
+ 1 - 2 (🏷️ int)
+ 2 - 3 (🏷️ int)
+ 3
+ m
+ m - 2 (🏷️ int)
+bee
+ sea
+ dee - e (🏷️ str)
+
+```
+.update
+'y': 'γ', 'greek': {'alpha':'α', 'beta': 'β', 'gamma': [1,2,{'theta': 'θ'}]}})
+ ad2.update({ ad2
+```↯ AttrDict ↯
+x - 1 (🏷️ str)
+y - γ (🏷️ str)
+zed - (3+5j) (🏷️ complex)
+kay
+ l
+ y
+ c
+ greet - hello (🏷️ str)
+ o[]
+ 0 - 1 (🏷️ int)
+ 1 - 2 (🏷️ int)
+ 2 - 3 (🏷️ int)
+ 3
+ m
+ m - 2 (🏷️ int)
+bee
+ sea
+ dee - e (🏷️ str)
+greek
+ alpha - α (🏷️ str)
+ beta - β (🏷️ str)
+ gamma[]
+ 0 - 1 (🏷️ int)
+ 1 - 2 (🏷️ int)
+ 2
+ theta - θ (🏷️ str)
+
+```
+.flatten
will flatten all the nests into a single level
+ ad2.flatten()
+```↯ AttrDict ↯
+x - 1 (🏷️ str)
+y - γ (🏷️ str)
+zed - (3+5j) (🏷️ complex)
+kay.l.y.c.greet - hello (🏷️ str)
+kay.l.y.c.o.0 - 1 (🏷️ int)
+kay.l.y.c.o.1 - 2 (🏷️ int)
+kay.l.y.c.o.2 - 3 (🏷️ int)
+kay.m - 2 (🏷️ int)
+bee.sea.dee - e (🏷️ str)
+greek.alpha - α (🏷️ str)
+ ... 4 more keys ...
+
+```
+.flatten_and_make_dataframe
is self explanatory
+ ad2.flatten_and_make_dataframe()
+ | 0 | +1 | +2 | +3 | +4 | +5 | +6 | +
---|---|---|---|---|---|---|---|
0 | +x | +1 | +None | +None | +None | +None | +NaN | +
1 | +y | +γ | +None | +None | +None | +None | +NaN | +
2 | +zed | +(3+5j) | +None | +None | +None | +None | +NaN | +
3 | +kay | +l | +y | +c | +greet | +hello | +NaN | +
4 | +kay | +l | +y | +c | +o | +0 | +1.0 | +
5 | +kay | +l | +y | +c | +o | +1 | +2.0 | +
6 | +kay | +l | +y | +c | +o | +2 | +3.0 | +
7 | +kay | +m | +2 | +None | +None | +None | +NaN | +
8 | +bee | +sea | +dee | +e | +None | +None | +NaN | +
9 | +greek | +alpha | +α | +None | +None | +None | +NaN | +
10 | +greek | +beta | +β | +None | +None | +None | +NaN | +
11 | +greek | +gamma | +0 | +1 | +None | +None | +NaN | +
12 | +greek | +gamma | +1 | +2 | +None | +None | +NaN | +
13 | +greek | +gamma | +2 | +theta | +θ | +None | +NaN | +