Using Counter Instances As Multisets
In the previous two lessons, I showed some practical applications of the
Counter class. In this lesson, I’ll go a little bit mathy and show you how counters can be a special type of set—the multiset.
00:13 A set is a collection of things where each item inside of it is unique. The concept is common enough that Python has included this as a built-in data type.
00:23 A multiset is a set without the uniqueness constraint. They’re often implemented in a way where you can know how many of each item there is inside. Does this sound familiar? Yep.
You can use the
Counter class as a multiset. Before getting into the details of multisets, I need to introduce you to one more method on the
So far, nothing you haven’t seen before. Here’s the new part. The
.elements() method returns an iterator of all the items in the counter. Let me put it in a list so you can see the results.
01:14 This allows you to reconstruct the contents of the original data, albeit in a different order. With that extra bit of info, I can now talk about multisets.
01:29 A set in math is a collection of things with unique members. Python has a built-in data type for handling sets. Here, I’ve just created one. Note how the multiple ones and fours end up having just a single instance in the set.
Now let’s try that with our favorite state … and the same idea, but this time the members are letters. There are cases in math where you want sets without the unique member restriction. Enter Python’s
You can use the
Counter object as a multiset. One place where you might want to use a multiset is when dealing with the prime factors of a number.
02:09 Let me multiply some primes together. Or thinking of that another way …
02:23 that’s three twos, four fives, and a seventeen multiplied together.
Putting these factors together in a counter gives a multiset of the prime factors of eighty-five thousand. Having that in place, you can determine the resulting number using the
.elements() method. First, let me create a variable to store the result.
Next I’m going to loop over the elements. Remember this will return each item in the multiset. So three twos, four fives, and a seventeen. Multiply that and store it into the
And with that done, you’ve got a
product variable containing the results. If you’re using Python 3.8 or greater, you can do this in even less code by using the
prod() function in the
03:35 And that gets you to the same place. If you’ve ever done anything with sets in Python, you’ll know that you can perform operations on them, combining them in interesting ways.
Counter provides this same functionality to enable you to use it as a multiset. Consider the case of knowing the inventory and then having someone shop.
That’s my inventory
Counter and my shopping cart
.subtract() method on
Counter updates the value in the counter, subtracting the corresponding amounts from the argument’s multiset.
The two apples and five oranges that were purchased in the cart have been subtracted from the inventory. Like the other methods on
Counter, you can use arguments to subtract.
04:43 Five less oranges. It also supports the dictionary-style notation.
04:58 Counters also support math operations. Consider two counters, each storing the sales for a given day.
The total sales for the two days can be found by adding the counters. Note that the
.subtract() method that I was showing you just before updates the
Counter object in place.
.addition() creates a new counter, combining the data stored in
day2 together into a third object.
Difference is also supported. The sales increment would be how much better you did on day two than day one. A couple things to notice here. Like addition, this is creating a new object. Don’t confuse the
.subtract() method with the
minus operator (
-). They both do subtraction, but have different effects.
06:05 The second thing to notice is how difference handles negative values. It ignores them. Day one has nine oranges. Day two has eight. The difference is a negative number, so it isn’t included at all.
06:18 This may or may not be the behavior you want. So be careful. You can combine multisets through both intersection and union operations. The intersection of two counters is the minimum values of the items in the two sets.
and operator (
&) is used for intersection. Union is done through the
or operator (
|). Unions combine the maximum values of the items in the two sets.
06:54 There are two more operators that I want to talk about that are a little bit weird. They’re both unary operators, which means they operate on a single object.
07:03 Consider an inventory with some negative values.
I always seem to end up owing my neighbors tomatoes. Applying the unary plus (
+) to the set, and you get a new counter with only the positive values from the inventory.
The tomatoes are gone. Doing the same thing with the unary minus (
-), and you get a new counter with only the negative values. But note that you’re getting a positive count of them. With a little clever coding, you could combine the idea of the unary plus and the unary minus and build your own subtraction that handled negative numbers without removing them.
I’ll leave that as an exercise for you. That’s it for your introduction to the
Counter class. Next up, I’ll summarize the course.
Become a Member to join the conversation.