The magic of the collections
Hi, everybody. Today I want to briefly summarize one of the great modules in Python: Collections
This module implements specialized container data types and provides an alternative to Python’s generic built-in containers, which can be found in the Lib/collections/init.py directory if you are interested in the source code
Based on my current learning experience, the following types are widely used:
The name of the | Simple explanation |
---|---|
defaultdict | Dict subclasses call factory functions to provide missing values |
counter | Dict subclasses used to evaluate hashable objects |
deque | A list-like container that can be manipulated from both ends |
namedtuple | Factory function for creating a tuple subclass with named fields |
OrderedDict | The dict that records the input order |
If you are like me, don’t panic when you see the words factory function, hash object, container, etc., I was confused when I first saw them and skipped them, but later I found that you don’t need to understand them. If you are interested, you can look them up yourself
defaultdict
Basic concept
“Defaultdict” is a container defined in the module named “Collections”. It takes a function (the default factory) as its argument. Default is set to “int”, which is 0. Defaultdict if the key does not exist, and returns and displays the default value.
Let me explain in human terms: a dict that does not report errors when a key is not found
Examples of application
For a normal dict example, if we create a dictionary named person and the key is name, age, we will raise a KeyError if we try to call person[‘city’] because there is no city:
person = {'name':'xiaobai'.'age'18} :print ("The value of key 'name' is : ",person['name'])
print ("The value of key 'city' is : ",person['city'])
Out: The value of key 'name' is : xiaobai
Traceback (most recent call last):
File "C:\Users\E560\Desktop\test.py", line 17, in <module>
print ("The value of key 'city' is : ",person['city'])
KeyError: 'city'
Copy the code
Now what if we try defaultDict again?
from collections import defaultdict
person = defaultdict(lambda : 'Key Not found') Key Not Found = 'key Not Found'
person['name'] = 'xiaobai'
person['age'] = 18
print ("The value of key 'name' is : ",person['name'])
print ("The value of key 'adress' is : ",person['city'[) Out: The value of The key'name' is : xiaobai
The value of key 'adress' is : Key Not found
Copy the code
There is no problem this time. In fact, the fundamental reason is that when we create defaultdict, the first parameter we pass is the default value of all keys, and then we add name and age. When we finally query, if the key exists, we output the corresponding value. If it doesn’t, it prints the value ‘Key Not Found’ that we specified.
In addition, because defaultdict is passed as the default value for all keys when we create it, we can use this feature to implement other functions, such as:
from collections import defaultdict
d = defaultdict(list)
d['person'].append("xiaobai")
d['city'].append("paris")
d['person'].append("student")
for i in d.items():
print(i)
Out: ('person'['xiaobai'.'student'])
('city'['paris'])
Copy the code
By default, all keys correspond to a list, so we can use the append method of list when assigning values. Or take this example:
from collections import defaultdict
food = (
('jack'.'milk'),
('Ann'.'fruits'),
('Arham'.'ham'),
('Ann'.'soda'),
('jack'.'dumplings'),
('Ahmed'.'fried chicken'),
)
favourite_food = defaultdict(list)
for n, f in food:
favourite_food[n].append(f)
print(favourite_food) Out: defaultdict (< class'list'{>,'jack': ['milk'.'dumplings'].'Ann': ['fruits'.'soda'].'Arham': ['ham'].'Ahmed': ['fried chicken']})
Copy the code
Much the same as above, here you can expand your imagination and believe that defaultDict may be available at some point
counter
Basic concept
Counter is a subclass of dict. Thus, it is an unordered collection in which the elements and their respective counts are stored as dictionaries. This is equivalent to bag or multiset in other languages.
A counter that returns a dictionary, where key is the element that appears, and value is the number of occurrences of that element
Examples of application
The counter has nothing to say, what can also do, count bai!
from collections import Counter
# count list
count_list = Counter(['B'.'B'.'A'.'B'.'C'.'A'.'B'.'B'.'A'.'C'])
print (count_list)
# count a tupleCount_tuple = Counter (,2,2,3,1,3,1,1,1 (2))print(count_tuple) Out: Counter ({'B': 5, 'A': 3.'C': 2})
Counter({1: 4, 2: 3, 3: 2})
Copy the code
Counter is generally not used for dict and Set counts, because a dict key is unique and a Set itself cannot have repeating elements
Now we can count the food tuples directly from the defaultDict example:
from collections import Counter
food = (
('jack'.'milk'),
('Ann'.'fruits'),
('Arham'.'ham'),
('Ann'.'soda'),
('jack'.'dumplings'),
('Ahmed'.'fried chicken'),
)
favourite_food_count = Counter(n for n,f in food) # count the number of occurrences of name
print(favourite_food_count)
Out: Counter({'jack': 2.'Ann': 2.'Arham': 1, 'Ahmed': 1})
Copy the code
deque
Basic concept
We can use deques when we need to add and remove elements quickly at both ends of the container. My personal understanding is that a deque is a container that can operate on both ends, similar to a list but faster than a list
Examples of application
There are many methods of deque, many of which are similar to lists and also support slicing
from collections import deque
d = deque()
d.append(1)
d.append(2)
d.append(3)
print(len(d))
print(d[0])
print(d[-1])
Out: 3
1
3
Copy the code
The great feature of deque is that we can operate from both ends:
d = deque([i for i in range(5)])
print(len(d))
# Output: 5
d.popleft() Delete and return the leftmost element
# Output: 0
d.pop() Delete and return the rightmost element
# Output: 4
print(d)
# Output: deque([1, 2, 3])
d.append(100) Add elements from the right end
d.appendleft(-100) Add elements from the far left
print(d)
# Output: deque([-100, 1, 2, 3, 100])
Copy the code
For example, we can specify the maximum length of a deque when we define it. Like list, deques also support the extend method to facilitate list concatenation, but deques provide bidirectional operation:
From collections import deque d = deque([1,2,3,4,5], maxlen=9)# Set the total length unchanged
d.extendleft([0]) Add a list from the leftD.e xtend ([June])# extend a list from the right end
print(d) Out: a deque ([0, 1, 2, 3, 4, 5, 6, 7, 8], maxlen = 9)Copy the code
Now d already has 9 elements, and maxlen=9, if we add elements from the left, the rightmost element is automatically removed, and vice versa:
d.append(100)
print(d)
d.appendleft(-100)
print(d)
Out: deque([1, 2, 3, 4, 5, 6, 7, 8, 100], maxlen=9)
deque([-100, 1, 2, 3, 4, 5, 6, 7, 8], maxlen=9)
Copy the code
Deque can also be used in many other ways, so please find your own treasure according to your own needs.
namedtuple
Basic concept
Name tuple. You might think of it as a tuple, and yes, I think of it as a tuple enhanced version of a namedtuple that turns a tuple into a convenient container. With namedtuple, we don’t have to use integer indexes to access the members of a tuple.
I think you can think of namedtuple as an immutable dictionary
Examples of application
First, let’s review how ordinary tuples access members:
person = ('xiaobai'18),print(the person [0]) Out: xiaobaiCopy the code
Now let’s look at the power of namedtuple:
from collections import namedtuple
Person = namedtuple('Person'.'name age city') This is similar to defining a class
xiaobai = Person(name="xiaobai", age=18, city="paris") # similar to creating a new object
print(xiaobai) Out: the Person (name ='xiaobai', age=18, city='paris')
Copy the code
We create a namedTuple very much like we define a class, where Person is the name of the class, and the second argument is the name of the value of the namedTuple. It feels like an attribute in the class, but we don’t need a comma to separate it.
print(xiaobai.name)
print(xiaobai.age)
print(Xiaobai. city) out: 18 ParisCopy the code
“Cool, cool dead,” Guo Degang can not help but admire here
This approach to class call properties is nice and useful in some real-world scenarios. One last thing to remember is that we can’t change the value of a namedtuple:
xiaobai.name = 'laobai'Out: Traceback (most recent call last): File"C:\Users\E560\Desktop\test.py", line 5, in <module>
xiaobai.name = 'laobai'
AttributeError: can't set attribute
Copy the code
OrderedDict
Basic concept
“OrderedDict” is itself a dict, but it is special in that it records the order in which the keys and values are inserted into the dict
Examples of application
from collections import OrderedDict
d = {}
d['a'] = 1
d['b'] = 2
d['c'] = 3
d['d'] = 4
print(d)
Out:{'a': 1, 'c': 3.'b': 2.'d'4} :Copy the code
As you can see, this is a normal dict because it’s out of order. Even if we add a, B,c, and D and assign value, the output order is not controllable. OrderedDict was created to solve this problem:
from collections import OrderedDict
d = OrderedDict()
d['a'] = 1
d['b'] = 2
d['c'] = 3
d['d'] = 4
print(d) Out: OrderedDict ([('a', 1), ('b', 2), ('c'And 3), ('d', 4))Copy the code
This output is much better because the insertion order is automatically recorded, and similarly, if we delete a key, the order of OrderedDict does not change:
from collections import OrderedDict
print("Before deleting:\n")
od = OrderedDict()
od['a'] = 1
od['b'] = 2
od['c'] = 3
od['d'] = 4
for key, value in od.items():
print(key, value)
print("\nAfter deleting:\n")
od.pop('c')
for key, value in od.items():
print(key, value)
print("\nAfter re-inserting:\n")
od['c'] = 3
for key, value in od.items():
print(key, value) Out:'a'(1),'b'And (2)'c'And (3)'d', 4)
After deleting:
('a'(1),'b'And (2)'d', 4)
After re-inserting:
('a'(1),'b'And (2)'d'(4),'c', 3)
Copy the code
conclusion
Today I gave you a brief introduction to some of the basic container types for Collections, including:
Container type | The characteristics of |
---|---|
defaultdict | A dict that does not report errors for a Key cannot be found |
counter | Counter where key is the occurrence of the element and value is the number of occurrences of the element |
deque | A list that can operate in both directions |
namedtuple | Use to create a tuple with named fields |
OrderedDict | Dict that records the order in which keys are entered |
I don’t think it’s too much of an overstatement to call them treasure, because these containers are very useful in real use scenarios, and I find that many tutorials don’t cover them, so I sincerely hope that they can help you. If THERE are any mistakes or omissions in my introduction, PLEASE comment on them and let’s make progress together!