Python 3

home

[advanced] Advanced Container Structures

array

The array is a type-specific list.


The array container provides a list of a uniform type. An array's type must be specified at initialization. A uniform type makes an array more efficient than a list, which can contain any type.


from array import array

myarray = array('i', [1, 2])

myarray.append(3)

print(myarray)           # array('i', [1, 2, 3])

print(myarray[-1])       # acts like a list
for val in myarray:
    print(val)

myarray.append(1.3)     # error

Available array types:

Type code C Type Python Type Minimum size in bytes
'c' char character 1
'b' signed char int 1
'B' unsigned char int 1
'u' Py_UNICODE Unicode character 2
'h' signed short int 2
'H' unsigned short int 2
'i' signed int int 2
'I' unsigned int long 2
'l' signed long int 4
'L' unsigned long long 4
'f' float float 4
'd' double float 8





Collections: deque

A "double-ended queue" provides fast adds/removals.


The collections module provides a variety of specialized container types. These containers behave in a manner similer to the builtin ones with which we are familiar, but with additional functionality based around enhancing convenience and efficiency. lists are optimized for fixed-length operations, i.e., things like sorting, checking for membership, index access, etc. They are not optimized for appends, although this is of course a common use for them. A deque is designed specifically for fast adds -- to the beginning or end of the sequence:


from collections import deque

x = deque([1, 2, 3])

x.append(4)               # x now [1, 2, 3, 4]
x.appendleft(0)           # x now [0, 1, 2, 3, 4]

popped = x.pop()          # removes '4' from the end

popped2 = x.popleft()     # removes '1' from the start

A deque can also be sized, in which case appends will push existing elements off of the ends:


x = deque(['a', 'b', 'c'], 3)      # maximum size:  3
x.append(99)                       # now: deque(['b', 'c', 99])  ('a' was pushed off of the start)
x.appendleft(0)                    # now: deque([0, 'b', 'c'])   (99 was pushed off of the end)




Collections: Counter

Counter provides a counting dictionary.


This structure inherits from dict and is designed to allow an integer count as well as a default 0 value for new keys. So instead of doing this:


c = {}
if 'a' in c:
    c['a'] = 0
else:
    c['a'] = c['a'] + 1

We can do this:


from collections import Counter

c = Counter()
c['a'] = c['a'] + 1

Counter also has related functions that return a list of its keys repeated that many times, as well as a list of tuples ordered by frequency:


from collections import Counter

c = Counter({'a': 2, 'b': 1, 'c': 3, 'd': 1})

for key in c.elements():
    print(key, end=' ')            # a a b c c c d

print(','.join(c.elements()))   # a,a,b,c,c,c,d


print(c.most_common(2))   # [('c', 3), ('a', 2)]
                         # 2 arg says "give me the 2 most common"

c.clear()                # set all counts to 0 (but not remove the keys)

And, you can use Counter's implementation of the math operators to work with multiple counters and have them sum their values:


c = Counter({'a': 1, 'b': 2})
d = Counter({'a': 10, 'b': 20})

print(c + d)                     # Counter({'b': 22, 'a': 11})




Collections: defaultdict

defaultdict is a dict that provides a default object for new keys.


Similar to Counter, defaultdict allows for a default value if a key doesn't exist; but it will accept a function that provides a default value.


A defaultdict with a default list value for each key

from collections import defaultdict

ddict = defaultdict(list)

ddict['a'].append(1)
ddict['b']

print(ddict)                    # defaultdict(<type 'list'>, {'a': [1], 'b': []})

A defaultdict with a default dict value for each key

ddict = defaultdict(dict)

print(ddict['a'])         # {}    (key/value is created, assigned to 'a')

print(list(ddict.keys()))       # dict_keys(['a'])

ddict['a']['Z'] = 5
ddict['b']['Z'] = 5
ddict['b']['Y'] = 10

      # defaultdict(<class 'dict'>, {'a': {'Z': 5}, 'b': {'Z': 5, 'Y': 10}})




[pr]