In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-15 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
It is believed that many inexperienced people have no idea about the evolution of counting methods in Python language. therefore, this paper summarizes the causes and solutions of the problems. Through this article, I hope you can solve this problem.
Sometimes, the way to solve problems succinctly and elegantly in Python changes over time. As Python evolves, so does the method of counting list elements.
Taking calculating the number of times an element appears in a list as an example, we can write many different implementations. When analyzing these methods, we don't focus on performance, we only consider the code style.
To understand these different implementations, we need to know some historical background. Fortunately, we live in a "future" world and have a time machine. Next, let's get on the time machine and go back to 1997.
If statement
On January 1, 1997, we used Python 1.4. Now that there is a list of different colors, we want to know the number of times each color appears in the list. Let's calculate it in a dictionary.
Colors = ["brown", "red", "green", "yellow", "yellow", "brown", "brown", "black"] color_counts = {} for c in colors: if color_counts.has_key (c): color_ counts[ c] = color_ counts[ c] + 1 else: color_ counts[ c] = 1
Note: we do not use + = because incremental assignments do not appear until Python 2.0. in addition, we do not use the idiom c in color_counts (idiom), because it was also invented in Python 2.2.
After running the above code, we will find that the color_counts dictionary now contains the number of occurrences of each color in the list.
> color_counts
{'brown': 3,' yellow': 2, 'green': 1,' black': 1, 'red': 1}
The above implementation is simple. We traverse each color and determine whether the color is in the dictionary. If not, add the color to the dictionary; if yes, increase the count of the color.
We can also rewrite the above code as follows:
Colors = ["brown", "red", "green", "yellow", "yellow", "brown", "brown", "black"] color_counts = {} for c in colors: if not color_counts.has_key (c): color_ counts[ c] = 0 color_ counts[ c] = color_ counts[ c] + 1
If the list is sparse (that is, there are a large number of colors that are not repeated in the list), this code may run a little slowly. Because we are now going to execute two statements instead of one. But we don't care about performance, we only focus on coding style. After thinking about it, we decided to adopt the new version of the code.
Try Code Block (Code Block)
On January 2, 1997, we still used Python 1.4. When we woke up this morning, we suddenly realized that our code follows the principle of "Look Before You Leap" (that is, checking every possible situation in advance), but in fact we should program according to the principle of "it is easier to get forgiveness than permission" (Easier to Ask Forgiveness, Than Permission, exception handling when something goes wrong), because the latter is more concise and elegant. Let's ReFactor the code with try-except code blocks:
Colors = ["brown", "red", "green", "yellow", "yellow", "brown", "brown", "black"] color_counts = {} for c in colors: try: color_ counts[ c] = color_ counts[ c] + 1 except KeyError: color_ counts[ c] = 1
Now, our code tries to increase the count of each color. If a color is not in the dictionary, a KeyError is thrown, and we then set the count of that color to 1.
Get method
On January 1st, 1998, we upgraded to Python 1.5. We decided to ReFactor the previous code, using the new get method in the dictionary.
Colors = ["brown", "red", "green", "yellow", "yellow", "brown", "brown", "black"] color_counts = {} for c in colors: color_ counts [c] = color_counts.get (c, 0) + 1
Now, our code iterates through each color to get the current count value for that color from the dictionary. If there is no such count value, the count value of the color defaults to 0, and then adds 1 to the value. Set the value of the corresponding key in the dictionary to the new count.
It's cool to write all the main code on one line, but we're not entirely sure it's more concise and elegant. We thought it might be a little too smart, so we canceled the refactoring.
Setdefault method
On January 1st, 2001, we are now using Python 2.0. We heard that the dictionary type now has a setdefault method and decided to use it to ReFactor our code. We also decided to use the newly added + = incremental assignment operator.
Colors = ["brown", "red", "green", "yellow", "yellow", "brown", "brown", "black"] color_counts = {} for c in colors: color_counts.setdefault (c, 0) color_ counts [c] + = 1
We call the setdefault method every time we loop, whether we need it or not. But doing so does make the code look more readable. We found this method to be more concise and elegant than the previous code, so we submitted this change.
Fromkeys method
On January 1st, 2004, we used Python 2.3. We heard that a new class method called fromkeys (class method) has been added to the dictionary, which can use the elements in the list as keys to build the dictionary. We refactored the code using a new approach:
Colors = ["brown", "red", "green", "yellow", "yellow", "brown", "brown", "black"] color_counts = dict.fromkeys (colors, 0) for c in colors: color_ counts [c] + = 1
This code creates a new dictionary with different colors as keys, and the value of each key is set to 0 by default. In this way, when we increase the value of each key, we don't have to worry about whether it has been set or not. We also don't need to check or handle exceptions in the code, which looks like an improvement. We decided to modify the code in this way.
Deduction (Comprehension) and set
On January 1st, 2005, we are now using Python 2.4. We found that we can solve the counting problem by using collections (released in Python 2.3and version 2.4 as a built-in type) and list derivation (released in Python 2.0). On further reflection, I recall that generator expressions (generator expressions) were also released in Python 2.4, and we decided not to use list deduction, but to use generator expressions instead.
Colors = ["brown", "red", "green", "yellow", "yellow", "brown", "brown", "black"] color_counts = dict (c, colors.count (c) for c in set (colors))
Note: we are not using dictionary inference here, because dictionary inference was not invented until Python 2.7.
It ran successfully, and there was only one line of code. But is the code concise and elegant enough?
We are reminded of the Zen of Python of Python, the guiding principle of Python programming that originated from a Python mailing list and quietly incorporated into Python 2.2.1. We enter import this in the REPL (read-eval-print loop, interactive interpreter) interface:
> import this
The Zen of Python, by Tim Peters
Beautiful is better than ugly. # Beauty is better than ugliness
Explicit is better than implicit. # clarity is better than implication
Simple is better than complex. # simplicity is better than complexity
Complex is better than complicated. # complexity is better than difficulty
Flat is better than nested. # flat is better than nesting
Sparse is better than dense. # sparse is better than dense
Readability counts. # easy to read and have a price
Special cases aren't special enough to break the rules. # the special case is not special enough to break the rules
Although practicality beats purity. # although utility beats purity
Errors should never pass silently. # mistakes should never slip away in silence
Unless explicitly silenced. # unless explicitly silenced
In the face of ambiguity, refuse the temptation to guess. # in the face of uncertainty, refuse the temptation to guess
There should be one-- and preferably only one-- obvious way to do it. # there should be one-rather only one-obvious implementation
Although that way may not be obvious at first unless you're Dutch. # maybe this method is not obvious at first, unless you are Dutch
Now is better than never. # doing it now is better than not doing it at all
Although never is often better than right now. # although it's usually better not to do it than to do it right away
If the implementation is hard to explain, it's a bad idea. # if implementation is hard to explain, it's a bad idea
If the implementation is easy to explain, it may be a good idea. # if the implementation is easy to explain, it may be a good idea
Namespaces are one honking great idea-- let's do more of those! # namespaces are a great idea, so let's use them more often
Our code becomes more complex, the time complexity increases from O (n) to O (N2), and it becomes uglier and less readable. It was an interesting attempt to change it that way, but the implementation of one line of code is not as simple and elegant as our previous approach. We have decided to revoke the amendment.
Defaultdict method
On January 1st, 2007, we used Python 2.5. We just found out that defaultdict has been added to the standard library. In this way, we can set the default key value of the dictionary to 0. Let's ReFactor the code using defaultdict:
From collections import defaultdict
Colors = ["brown", "red", "green", "yellow", "yellow", "brown", "brown", "black"] color_counts = defaultdict (int) for c in colors: color_ counts [c] + = 1
That for loop is so simple now! This must be more concise and elegant.
We found that the behavior of the variable color_counts is a little different now, but it does inherit the features of the dictionary and supports all the same mapping capabilities.
> color_counts
Defaultdict (, {'brown': 3,' yellow': 2, 'green': 1,' black': 1, 'red': 1})
Instead of converting color_counts into a dictionary, we assume that other code also uses the duck type (duck typing, one of the dynamic types in Python, meaning that other code treats color_counts as a dictionary type) and does not change this dictionary-like object.
Counter class
On January 1st, 2011, we used Python 2.7. We have been told that code written in defaultdict is no longer the most concise and elegant way to count the number of color occurrences. A new Counter class has been introduced in Python 2.7, which can completely solve our problem.
From collections import Counter
Colors = ["brown", "red", "green", "yellow", "yellow", "brown", "brown", "black"] color_counts = Counter (colors)
Is there any easier way than this? This must be the most concise and elegant implementation.
Like defaultdict, the Counter class returns a dictionary-like object (actually a subclass of the dictionary). It was enough to meet our needs, so we did it.
> color_counts
Counter ({'brown': 3,' yellow': 2, 'green': 1,' black': 1, 'red': 1})
Performance consideration
Note that none of us focused on efficiency when writing these implementations. Most methods have the same time complexity (O (n)), but the running time varies with different Python language implementations (such as CPython, PyPy, or Jython).
Although performance is not our main concern, I tested the run time under the implementation of CPython 3.5.0. From this, you will find an interesting phenomenon: as the density of the color elements in the list (that is, the number of the same elements) changes, the relative efficiency of each implementation method will be different.
According to the Python Zen, "there should be one-rather there is only one obvious way to implement it." The state mentioned in this sentence is worth pursuing, but the truth is that there is not always only one obvious way. This "obvious" approach will change over time, demand, and professionalism.
After reading the above, have you mastered the evolution of counting methods in the Python language? If you want to learn more skills or want to know more about it, you are welcome to follow the industry information channel, thank you for reading!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.