Coding With Fun
Home Docker Django Node.js Articles Python pip guide FAQ Policy

10 tips for speeding up Python programming


Jun 01, 2021 Article blog


Table of contents


Programming is an interesting thing, and programming with Python is even more interesting because there are many different ways to implement a feature in Python H owever, most of the time there are some preferred implementation methods, which some people call Pythonic A common feature of Pythonic is that the implementation code is concise.

Programming in Python or any coding language is not rocket-like science, it's all about skill. I f you're interested in experimenting with Pythonic coding, these technologies will soon be part of our toolkit, and we'll find it more and more natural to use them in our projects. So let's explore some of these simple tips.

1. Negative index

People like to use sequences because when we know the order of the elements, we can manipulate them sequentially. S trings, tuples, and lists are the most common sequence data types in Python W e can use indexes to access individual items. L ike other mainstream programming languages, Python supports a 0-based index in which we use zero to access the first element in parentheses. In addition, we can use tile objects to retrieve specific elements of the sequence, as shown in the following code example.

>>> # Positive Indexing 
... numbers = [1, 2, 3, 4, 5, 6, 7, 8] 
... print("First Number:", numbers[0]) 
... print("First Four Numbers:", numbers[:4]) 
... print("Odd Numbers:", numbers[::2]) 
... First Number: 1 
First Four Numbers: [1, 2, 3, 4] 
Odd Numbers: [1, 3, 5, 7] 

However, Python went one step further by supporting negative indexes. S pecifically, we can use -1 to refer to the last element in the sequence and count backward. F or example, the index of the last element is -2, and so on. Importantly, negative indexes can also be used with positive indexes in sliced objects.

>>> # Negative Indexing
... data_shape = (100, 50, 4)
... names = ["John", "Aaron", "Mike", "Danny"] 
... hello = "Hello World!" 
... 
... print(data_shape[-1]) 
... print(names[-3:-1]) 
... print(hello[1:-1:2]) 
... 4 
['Aaron', 'Mike']
el ol 

2. Check that the container is empty

Containers are those types of container data that can store other data. S ome of the built-in containers that are often used are tuples, lists, dictionaries, and collections. W hen working with these containers, we often need to check that they contain any elements before doing anything else. I ndeed, we can check the length of these containers, which corresponds to the number of items stored. W hen the length is zero, the container is empty. Here's a simple example.

if len(some_list) > 0:
    # do something here when the list is not empty 
else:
    # do something else when the list is empty 

However, this is not the best Pythonic approach. I nstead, we can simply examine the container itself, which will be evaluated when the container True contains elements. Although the following code shows you the main container data types, this usage can also be applied to strings (that is, any non-empty string is True).

>>> def check_container_empty(container): 
...     if container: 
...         print(f"{container} has elements.") 
...     else: 
...         print(f"{container} doesn't have elements.") 
... 
... check_container_empty([1, 2, 3]) 
... check_container_empty(set()) 
... check_container_empty({"zero": 0, "one": 1}) 
... check_container_empty(tuple()) 
... [1, 2, 3] has elements. 
set() doesn't have elements.
{'zero': 0, 'one': 1} has elements. 
() doesn't have elements. 

3. Use Split() to create a list of strings

We often use strings as identifiers for specific objects. F or example, we can use strings as keys in a dictionary. I n a data science project, strings are usually column names for data. W hen you select multiple columns, you inevitably need to create a list of strings. I ndeed, we can create strings using the text in the list. H owever, we have to write pairs of quotation marks to enclose each string, which is a bit cumbersome for "lazy" people. Therefore, I prefer to use the split() method of strings to create a list of strings, as shown in the following snippet.

>>> # List of strings
... # The typical way
... columns = ['name', 'age', 'gender', 'address', 'account_type']
... print("* Literals:", columns)
...
... # Do this instead
... columns = 'name age gender address account_type'.split()
... print("* Split with spaces:", columns)
...
... # If the strings contain spaces, you can use commas instead
... columns = 'name, age, gender, address, account type'.split(', ')
... print("* Split with commas:", columns)
...
* Literals: ['name', 'age', 'gender', 'address', 'account_type']
* Split with spaces: ['name', 'age', 'gender', 'address', 'account_type']
* Split with commas: ['name', 'age', 'gender', 'address', 'account type']

As shown above, split() By default, this method uses spaces as separators and creates a list of strings based on strings. It is important to note that when you create a list of strings that contain some elements that contain spaces, you can choose to use other types of separators (for example, commas).

This usage is inspired by some built-in features. F or example, when you create a tuple class, we can do this: Student = namedtuple(“Student”, [“name”, “gender”, “age”]) T he string list specifies the "properties" of the tuple. H owever, you can also define the class to support it locally by: Student = namedtuple(“Student”, “name gender age”) For another instance, create an Enum class that supports the same alternative solution.

(Recommended tutorial: python tutorial)

4. Three-way expression

In many use cases, we need to define variables with specific values based on conditions, and we can simply use if ... else statement to check the condition. H owever, it requires a few lines of code. I f you are working with assignments for only one variable, you may need to use a troy expression that checks the condition and completes the assignment with just one line of code. I n addition, it's shorter in format, making the code cleaner. Consider the following example.

# The typical way
if score > 90:
    reward = "1000 dollars"
else:
    reward = "500 dollars"
# Do this instead
reward = "1000 dollars" if score > 90 else "500 dollars"

Sometimes we can get some data from defined functions, and we can take advantage of this and write a simple operation of a troy expression, as shown below.

# Another possible scenario
# You got a reward amount from somewhere else, but don't know if None/0 or not
reward = reward_known or "500 dollars"
# The above line of code is equivalent to below
reward = reward_known if reward_known else "500 dollars"

5. Statement with file object

We often need to read data from a file and write it to a file. The most common approach is to simply open a file using the built-in open() function, which creates a file object that we can manipulate.

>>> # Create a text file that has the text: Hello World!
...
... # Open the file and append some new data
... text_file0 = open("hello_world.txt", "a")
... text_file0.write("Hello Python!")
...
... # Open the file again for something else
... text_file1 = open("hello_world.txt")
... print(text_file1.read())
...
Hello World!

In the previous snippet, we started with a text file with the text “ Hello World!” 。 W e then attach some new data to the file. H owever, after a while, we want to work on the file again. W hen we read a text file, it still has old data. In other words, the attached text is not included in the text file.

This is because we didn't close the file object in the first place. I f you do not close the file, you cannot save the changes. I ndeed, close() can explicitly call the method on the file object. H owever, we can do this “with” statement, which automatically closes the file object for us, as shown below. When we're done with the file, we can verify that the file is closed by accessing the closed property of the file object.

>>> with open("hello_world.txt", "a") as file:
...     file.write("Hello Python!")
...
... with open("hello_world.txt") as file:
...     print(file.read())
...
... print("Is file close?", file.closed)
...
Hello World!Hello Python!Hello Python!
Is file close? True

In more general terms, with statement is a syntax that uses context managers in Python T he previous example involved file operations because these files are shared resources that we are responsible for releasing. T he context manager can help us get the job done. As shown earlier, when the file operation is over, the file is automatically closed with statement.

6. Evaluate multiple conditions

Typically, we need to evaluate multiple conditions. T here are several possible scenarios. F or values, we can compare the same variable multiple times. In this case, we can link these comparisons.

# Multiple Comparisons
# The typical way
if a < 4 and a > 1:
    # do something here# Do this instead
if 1 < a < 4:
    # do somerthing here

In other cases, we can make multiple equal comparisons, and we can use the following in keyword for member testing.

# The typical way
if b == "Mon" or b == "Wed" or b == "Fri" or b == "Sun":
    # do something here# Do this instead, you can also specify a tuple ("Mon", "Wed", "Fri", "Sun")
if b in "Mon Wed Fri Sun".split():
    # do something here

Another technique is to use the built-in all() and any() functions to evaluate the functionality of multiple conditions. S pecifically, the all() function evaluates when all the elements in the iteration are True so the function is suitable for replacing a series of AND logical comparisons. O n the other hand, the any() function is calculated to True when any element in the iteration is True so it is appropriate to replace a series of OR logical operations. The relevant example is shown below.

# The typical ways
if a < 10 and b > 5 and c == 4:
    # do somethingif a < 10 or b > 5 or c == 4:
    # do something# Do these instead
if all([a < 10, b > 5, c == 4]):
    # do somethingif any([a < 10, b > 5, c == 4]):
    # do something

7. Use the default value in the function declaration

In almost all Python projects, most code involves creating and calling functions. I n other words, we keep dealing with function declarations and refactoring. I n many cases, we need to call a function multiple times. D epending on the set of parameters, the functionality will be slightly different. H owever, sometimes a set of parameters may be more commonly used than others, in which case we should consider setting a default value when declaring a function. Consider the following simple example.

# The original form:
def generate_plot(data, image_name):
    """This function creates a scatter plot for the data"""
    # create the plot based on the data
    ...
    if image_name:
        # save the image
        ...# In many cases, we don't need to save the image
generate_plot(data, None)# The one with a default value
def generate_plot(data, image_name=None):
    pass# Now, we can omit the second parameter
generate_plot(data)

One thing to note is that if you want to work with variable data types (such as lists, collections) when setting default values, make sure that you use None instead of constructors (for arg_name = [] B ecause Python creates a function object at a defined location, the blank list provided is "stuck" by the function object. I n other words, a function object is not created immediately when it is called. Instead, we'll work with the same function object in memory, including the default variable object it originally created, which can cause unexpected behavior.

8. Use counters for element counting

When we have multiple items in a list, tuple, or string (for example, multiple characters), we often want to calculate how many elements are in each item. To do this, you can write some tedious code for this feature.

>>> words = ['an', 'boy', 'girl', 'an', 'boy', 'dog', 'cat', 'Dog', 'CAT', 'an','GIRL', 'AN', 'dog', 'cat', 'cat', 'bag', 'BAG', 'BOY', 'boy', 'an']
... unique_words = {x.lower() for x in set(words)}
... for word in unique_words:
...     print(f"* Count of {word}: {words.count(word)}")
...
* Count of cat: 3
* Count of bag: 1
* Count of boy: 3
* Count of dog: 2
* Count of an: 5
* Count of girl: 1

As shown above, we must first create a collection that contains only unique words. W e then iterate through the word set and use the count() method to find out what happens to each word. However, there is a better way to use Counter class to accomplish this counting task.

>>> from collections import Counter
...
... word_counter = Counter(x.lower() for x in words)
... print("Word Counts:", word_counter)
...
Word Counts: Counter({'an': 5, 'boy': 4, 'cat': 4, 'dog': 3, 'girl': 2, 'bag': 2})

The counter class is available in the collections module. T o use this class, we simply create a generator: , x.lower() for x in words each item will be counted. As we can see, Counter object is a dict mapping object, with each key corresponding to the only item in the word list, and the value is the count of those items.

In addition, if we are interested in finding the items that appear most frequently in the word list, we can Counter advantage of the most_common() method. T he following code shows this usage. W e only need to specify an integer (N) to find the N items most frequently from the list. With instructions, the object will also be used with other sequence data, such as strings and tuples.

>>> # Find out the most common item
... print("Most Frequent:", word_counter.most_common(1))
Most Frequent: [('an', 5)]
>>> # Find out the most common 2 items
... print("Most Frequent:", word_counter.most_common(2))
Most Frequent: [('an', 5), ('boy', 4)]

9. Sort by order requirements

In many projects, sorting items in a list is a common task. T he most basic sorting is based on numbers or alphabetical order, and we can use the built-in sorted() function. B y default, the sorted() function sorts the list in ascending order (in fact, it can be iterative). I f you specify the reverse parameter as True you can get the item in descending order. Some simple usages are shown below.

>>> # A list of numbers and strings
... numbers = [1, 3, 7, 2, 5, 4]
... words = ['yay', 'bill', 'zen', 'del']
... # Sort them
... print(sorted(numbers))
... print(sorted(words))
...
[1, 2, 3, 4, 5, 7]
['bill', 'del', 'yay', 'zen']
>>> # Sort them in descending order
... print(sorted(numbers, reverse=True))
... print(sorted(words, reverse=True))
...
[7, 5, 4, 3, 2, 1]
['zen', 'yay', 'del', 'bill']

In addition to these basic usages, we can specify key parameters so that complex items, such as tuple lists, can be sorted. Consider the following example of this situation.

>>> # Create a list of tuples
... grades = [('John', 95), ('Aaron', 99), ('Zack', 97), ('Don', 92), ('Jennifer', 100), ('Abby', 94), ('Zoe', 99), ('Dee', 93)]
>>> # Sort by the grades, descending
... sorted(grades, key=lambda x: x[1], reverse=True)
[('Jennifer', 100), ('Aaron', 99), ('Zoe', 99), ('Zack', 97), ('John', 95), ('Abby', 94), ('Dee', 93), ('Don', 92)]
>>> # Sort by the name's initial letter, ascending
... sorted(grades, key=lambda x: x[0][0])
[('Aaron', 99), ('Abby', 94), ('Don', 92), ('Dee', 93), ('John', 95), ('Jennifer', 100), ('Zack', 97), ('Zoe', 99)]

The above code shows us two examples of advanced sorting by utilizing the lambda function passed to the key argument. T he first sorts items in descending order, and the second sorts items in the default ascending order. W e're going to combine these two requirements, and if you consider using the reverse parameter, you might get an incorrect sorting tree, because if you try to sort by multiple criteria, the reverse parameter will apply to all parameters. See the snippet below.

>>> # Requirement: sort by name initial ascending, and by grades, descending
... # Both won't work
... sorted(grades, key=lambda x: (x[0][0], x[1]), reverse=True)
[('Zoe', 99), ('Zack', 97), ('Jennifer', 100), ('John', 95), ('Dee', 93), ('Don', 92), ('Aaron', 99), ('Abby', 94)]
>>> sorted(grades, key=lambda x: (x[0][0], x[1]), reverse=False)
[('Abby', 94), ('Aaron', 99), ('Don', 92), ('Dee', 93), ('John', 95), ('Jennifer', 100), ('Zack', 97), ('Zoe', 99)]
>>> # This will do the trick
... sorted(grades, key=lambda x: (x[0][0], -x[1]))
[('Aaron', 99), ('Abby', 94), ('Dee', 93), ('Don', 92), ('Jennifer', 100), ('John', 95), ('Zoe', 99), ('Zack', 97)]

As you can see, neither is valid by setting the reverse parameter to True or False I nstead, the trick is to reverse the scores, so when you sort in the default ascending order, the scores are sorted in reverse because the values are reversed. However, this method has a warning because inversion can only be used for numeric values, not strings.

10. Don't forget defaultdict

A dictionary is an effective type of data that allows us to store data as key-value pairs. I t requires that all keys be hashed, and storing this data may involve the use of hash tables. T his approach allows data retrieval and insertion at O(1) efficiency. H owever, it should be noted that in addition to the built-in dict type, we have other dictionaries available. A mong them, I want to discuss defaultdict type. Unlike the built-in dict type, defaultdict allows us to set the default factory function, which creates elements when the key does not exist.

>>> student = {'name': "John", 'age': 18}
... student['gender']
...
Traceback (most recent call last):
  File "<input>", line 2, in <module>
KeyError: 'gender'

Suppose we're working on words and want to group characters that are the same as lists, and those lists are associated with characters that are keys. T his is a childish implementation using the built-in dict type. It is important to check whether the dict object has a letter key, because if the key does not exist, calling the append() method throws a KeyError exception.

>>> letters = ["a", "a", "c", "d", "d", "c", "a", "b"]
... final_dict = {}
... for letter in letters:
...     if letter not in final_dict:
...         final_dict[letter] = []
...     final_dict[letter].append(letter)
...
... print("Final Dict:", final_dict)
...
Final Dict: {'a': ['a', 'a', 'a'], 'c': ['c', 'c'], 'd': ['d', 'd'], 'b': ['b']}

Let's look at how to write cleaner code using defaultdict Although the example is simple, it only gives us some ideas about defaultdict class, which allows us to work with keys that do not exist in dictionary objects.

>>> from collections import defaultdict
...
... final_defaultdict = defaultdict(list)
... for letter in letters:
...     final_defaultdict[letter].append(letter)
...
... print("Final Default Dict:", final_defaultdict)
...
Final Default Dict: defaultdict(<class 'list'>, {'a': ['a', 'a', 'a'], 'c': ['c', 'c'], 'd': ['d', 'd'], 'b': ['b']})

(Recommended micro-course: python3 basic micro-course)

conclusion

Before reading this article, we may have learned some tricks, but we hope to still know them. Practicing these idioms in your project will make your Python code more readable and performing.

Article Source: Public No. - Little White School Vision

Author: Peanuts

These are some of the 10 tips for speeding up Python programming.