Python 3home |
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 |
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)
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})
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}})