Posted on Leave a comment

Matplotlib Boxplot – A Helpful Illustrated Guide

Do you want to plot numerical data? And do it in a beautiful, engaging, and scientifically sound way? And do all of this in a few simple lines of code? You’re in the right place!

A great way to plot numerical data is the matplotlib boxplot. It displays the median, the interquartile range, and outliers of the data.

How can you visualize your data with the boxplot?

  1. Get that data into an array-like object – list, NumPy array, pandas series, etc.
  2. Pass it to plt.boxplot().
  3. Call plt.show().

As a result, matplotlib will draw a lovely boxplot for you.

import matplotlib.pyplot as plt plt.boxplot(data)
plt.show()

The boxplot clearly shows the median of the data (orange line), the upper and lower quartiles (top and bottom parts of the box) and outliers (the circles at the top and/or bottom of the ‘whiskers’ of the plot).

There are quite a few things we can do to improve this plot – we don’t even know what the data represents! – so let’s dive into a more detailed example.

Try It Yourself:

You can play with a simple example here in our interactive Python shell online. The resulting plot will be stored in a .png file in the online project (just click on “files”):

Matplotlib Boxplot Example

The boxplot is an essential tool you should use when when exploring datasets. The matplotlib boxplot function accepts a lot of keyword arguments and so can seem quite intimidating if you look at the docs. So, I’ll cover the most essential ones that you will use most often.

Boxplots show the distribution of numerical data, in particular they show if it is skewed and whether there are unusual observations/outliers. They are very helpful if you are dealing with a large amount of data and want to see a visual summary – in this way, they are similar to histograms. They give you ability to compare multiple distributions at the same time because you can plot many boxplots on one Figure. This is not really possible with histograms – any more than 3 and it starts to look crowded.

As this is an article about how to best work with boxplots, I will not go into detail about how I generated the datasets. However, if you want to follow along, I am using Seaborn’s tips dataset and you can find more info here.

Let’s assume you are a waiter/waitress at a restaurant and you have recorded the total bill in USD for each table you waited from Thursday – Sunday last week. You want to visualize this data to understand which days, if any, are the best to work. The total bill for all the days is stored in total_bill and the total bill for each day is stored in the variables thu, fri, sat and sun respectively.

Let’s plot total bill and add some info to the axes and a title.

plt.boxplot(total_bill)
plt.title('Total Bill ($) for All Days Last Week')
plt.ylabel('Total Bill ($)')
plt.show()

This looks much better and it is now easy to understand what the boxplot is showing. We can see that the median bill for each table is about 17 USD and that the interquartile range (upper quartile – lower quartile) is from 24 – 14 = 10 USD. There are about 8 outliers where the bill was more than 40 USD and the lowest bill was about 3 USD.

Matplotlib Boxplot Multiple

Boxplots let you compare the distributions of different datasets. So, you will almost always want to plot more than one boxplot on a figure. To do this, pass the data you want to plot to plt.boxplot() as a list of lists.

# Create list of lists
all_days = [thu, fri, sat, sun] # Pass to plt.boxplot()
plt.boxplot(all_days)
plt.show()

Here I combined all the individual datasets into a list of lists all_days and passed that to plt.boxplot(). Matplotlib automatically places the four boxplots a nice distance apart but does not label the x-axis for us. Let’s do that now.

Matplotlib Boxplot Labels

To label each boxplot, pass a list of strings to the labels keyword argument. If you have several labels, I recommend you create this first before passing it to plt.boxplot().

# Create data and labels first
all_days = [thu, fri, sat, sun]
labels = ['Thu', 'Fri', 'Sat', 'Sun'] # Plot data and labels
plt.boxplot(all_days, labels=labels)
plt.ylabel('Total Bill ($)')
plt.show()

Great, now we can see that each boxplot represents the total bill for each day of the week and which day is which.

Make sure your list of labels is the same length as the number of boxplots and that you pass them in the order you want them to appear. If you don’t want to label a particular boxplot, pass an empty string ''. Finally, you can also pass ints and floats if you desire.

all_days = [thu, fri, sat, sun] # Second label is an empty string, fourth is a float
labels = ['Thu', '', 'Sat', 999.9] plt.boxplot(all_days, labels=labels)
plt.show()

Your boxplots look much better now but the matplotlib default settings are quite boring. It’s important to make your visualizations engaging and one of the best ways to do this is to add some color.

Matplotlib Boxplot Fill Color

To just fill the color of the box, you first need to set patch_artist=True. Why is this?

Under the hood, plt.boxplot() returns a dictionary containing each part of the boxplot and these parts are Line2D objects. However, by definition, these do not have an edgecolor or facecolor – lines just have one color.

To color inside the box, you must turn it into a Patch object which, by definition, has a facecolor.

To modify the box, use the boxprops (box properties) keyword argument. It accepts a dictionary and the key-value pair you need is 'facecolor' plus a color.

# Turn box into a Patch so that it has a facecolor property
plt.boxplot(total_bill, patch_artist=True, # Set facecolor to red boxprops=dict(facecolor='r'))
plt.show()

Note that if you don’t set patch_artist=True, you will get an error.

# Not setting patch_artist=True gives an error
plt.boxplot(total_bill, # Set facecolor to red boxprops=dict(facecolor='r'))
plt.show()
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-97-d28bb5a14c71> in <module> 2 plt.boxplot(total_bill, 3 # Set facecolor to red
----> 4 boxprops=dict(facecolor='r')) 5 plt.show() AttributeError: 'Line2D' object has no property 'facecolor'

If you also want to change the color of the line surrounding the box, pass the additional argument color=c for some color c to boxprops.

# Turn box into a Patch so that it has a facecolor property
plt.boxplot(total_bill, patch_artist=True, # Set facecolor and surrounding line to red boxprops=dict(facecolor='r', color='r'))
plt.show()

Perfect, now you know how to change the box’s color, let’s look at changing the other parts.

Matplotlib Boxplot Color

You can change any part of a boxplot to any color you want.

There are a 6 parts you can color:

  1. box – the main body of the boxplot
  2. median – horizontal line illustrating the median of the distribution
  3. whiskers – vertical lines extending to the most extreme (non-outlier) data points
  4. caps – horizontal lines at the ends of the whiskers
  5. fliers – points above/below the caps representing outliers
  6. mean – horizontal line illustrating the mean of the distributions (by default not included)

In the above image, I’ve labelled the first 5 parts but have not included the mean as it is not often used with boxplots.

Each of the parts can be modified by a <part>props keyword argument, similar to the boxprops one above.

The available keyword arguments are:

boxprops, medianprops, whisperprops, capprops, flierprops, meanprops

For example, write this to set the color of the median line to red

medianprops=dict(color='red')

They all accept the color keyword argument and the value can be any matplotlib color string. The only different one is flierprops which also accepts markeredgecolor to color the line around the outliers.

Finally, remember to set patch_artist=True if you want to change the fill color of the box.

Let’s look at an example where I turn the entire boxplot red. Since there are so many keyword arguments to pass, I will first create a dictionary and use the ** operator to unpack it in my plt.boxplot() call.

# Set color to red
c = 'r' # Create dictionary of keyword aruments to pass to plt.boxplot
red_dict = {'patch_artist': True, 'boxprops': dict(color=c, facecolor=c), 'capprops': dict(color=c), 'flierprops': dict(color=c, markeredgecolor=c), 'medianprops': dict(color=c), 'whiskerprops': dict(color=c)} # Pass dictionary to boxplot using ** operator to unpack it
plt.boxplot(total_bill, **red_dict)
plt.show()

First I created a variable c to hold the color string in. This means that if I want to change the color to green, I only have to change one line of code – c = 'g' – and it will change the color everywhere.

Then I created red_dict where the key-value pairs is a string and dictionary. The first key is patch_artists=True and the other keys are the <part>props keyword argument. Finally, I created a boxplot of total_bill and colored it red by unpacking red_dict with the ** operator.

If you want to brush up on your dictionary knowledge, check out my article the ultimate guide to dictionaries.

The red plot is much more engaging than the standard matplotlib colors. But, because the median line was the same color as everything else, you lost some information it was showing. One way to rectify this is to set to median line to black with'medianprops': dict(color='k') in red_dict. The result is shown above.

Matplotlib Boxplot Width

To change the width of a boxplot, pass a float to to the widths keyword argument in plt.boxplot(). It represents the fraction of space the box takes up on the figure.

If you have one boxplot, the scalar represents the percentage of the plot the box takes up.

plt.boxplot(total_bill, widths=1)
plt.show()

Here the box takes up 100% of the width as widths=1.

plt.boxplot(total_bill, widths=0.1)
plt.show()

Here the box only takes up 10% of the space as widths=0.1.

If you plot multiple boxplots on the same figure and pass a float to widths, all boxes will be resized to take up that fraction of space in their area of the plot.

# Boxes take up 100% of their allocated space
plt.boxplot(all_days, widths=1)
plt.show()

Here each boxplot takes up 100% of the space allocated as widths=1.

# Boxes take up 80% of their allocated space
plt.boxplot(all_days, widths=0.8)
plt.show()

Here each boxplot takes up 80% of the space allocated to them as widths=0.8.

You can set the width of each boxplot individually by passing a list to widths instead of a scalar. In [83]:

plt.boxplot(all_days, widths=[0.1, 0.9, 0.5, 0.8], labels=['10%', '90%', '50%', '80%'])
plt.show()

Here I have labelled the amount of horizontal space each box takes up. Although it is possible to do this, I do not recommend it. It adds another dimension to your boxplot but isn’t showing any new information. I personally think that widths=0.8 looks best, but you are free to choose any size you want. Just make sure that your boxplots are the same width so as not to confuse your reader.

Matplotlib Boxplot Horizontal

To create a horizonal boxplot in matplotlib, set the vert keyword argument to False.

plt.boxplot(total_bill, vert=False)
plt.show()

Conclusion

That’s it, you now know all the basics of boxplots in matplotlib!

You’ve learned how to plot single and multiple boxplots on one figure. You can label them whatever you want and change the color of any of the 6 parts to anything you can imagine. Finally, you’ve learned to customize the width of your plots and plot horizontal ones as well.

There is still more to be learned about boxplots such as changing the outlier marker, adding legends, sorting them by groups and even working with them and the pandas library. But I’ll leave that for another article.

Where To Go From Here?

Do you wish you could be a programmer full-time but don’t know how to start?

Check out the pure value-packed webinar where Chris – creator of Finxter.com – teaches you to become a Python freelancer in 60 days or your money back!

https://tinyurl.com/become-a-python-freelancer

It doesn’t matter if you’re a Python novice or Python pro. If you are not making six figures/year with Python right now, you will learn something from this webinar.

These are proven, no-BS methods that get you results fast.

This webinar won’t be online forever. Click the link below before the seats fill up and learn how to become a Python freelancer, guaranteed.

https://tinyurl.com/become-a-python-freelancer

Posted on Leave a comment

Python List count()

This tutorial shows you everything you need to know to help you master the essential count() method of the most fundamental container data type in the Python programming language.

Definition and Usage:

The list.count(x) method counts the number of occurrences of the element x in the list.

Here’s a short example:

>>> lst = [1, 2, 42, 2, 1, 42, 42]
>>> lst.count(42)
3
>>> lst.count(2)
2

In the first line of the example, you create the list lst. You then count the number of times the integer values 42 and 2 appear in the list.

Code Puzzle — Try It Yourself:

Now you know the basics. Let’s deepen your understanding with a short code puzzle—can you solve it?

You can also solve this puzzle and track your Python skills on our interactive Finxter app.

Syntax: You can call this method on each list object in Python. Here’s the syntax:

list.count(value)

Arguments:

Argument Description
value Counts the number of occurrences of value in list. A value appears in the list if the == operator returns True.

Return value: The method list.count(value) returns an integer value set to the number of times the argument value appears in the list. If the value does not appear in the list, the return value is 0.

Python List Count Values

Python List Count Duplicates

Python List Count Unique Values and Strings

Python List Count All Elements

Python List Count Lambda

Python List Count With Condition

Python List Count If

Python List Count Greater Than

Python List Count Smaller Than

Python List Count Regex

Python List Count Matches

Python List Count Wildcard

Python List Count Not Working

Python List Count Runtime Complexity

Python List Reference Count

Python List Count to Dict

Python List Count Tuples

Python List Count Zero / Non-Zero

Python List Count and Sort

Python List Count Slow

Python List Count Group By

Python List Count vs Len

Python List reverse() Time Complexity

The time complexity of the reverse() operation is O(n) for a list with n elements. The standard Python implementation cPython “touches” all elements in the original list to move them to another position. Thus, the time complexity is linear in the number of list elements.

You can see a plot of the time complexity of the reverse() method for growing list size here:

Time complexity of Python List reverse()

The figure shows how the elapsed time of reversing lists with growing number of elements grows linear to the number of elements.

If you’re interested in the code I used to generate this plot with Matplotlib, this is it:

import matplotlib.pyplot as plt
import time y = []
for i in [100000 * j for j in range(10,100)]: lst = list(range(i)) t0 = time.time() x = lst.reverse() t1 = time.time() y.append(t1-t0) plt.plot(y)
plt.xlabel("List elements (10**5)")
plt.ylabel("Time (sec)")
plt.show()

Python List reverse() In Place

If you call the list.reverse() method on any list object in Python, it reverses the list elements of this particular list object. You say that the reverse method happens in place.

This is a common mistake of many Python beginners. They assume that the reverse() method creates a new list with the elements in reversed order. This is not the case: the reverse() method modifies only the existing list object.

You can see this in the following example:

>>> lst = [1, 2, 3]
>>> lst.reverse()
>>> lst
[3, 2, 1]

In the example, you only reversed the existing list lst. But you didn’t create a new list!

Python List reverse() None

The return value of the list.reverse() method is None. Why? Because the method reverses the list in place. This means that no new list is created. Instead, the method modifies the old list object.

You’ve seen an example of this in the previous section.

Python List Reverse List Without reverse()

You can also reverse a list without using the reverse() method. Let’s have a look at the following table that shows all reverse() alternatives:

Method Description
lst.reverse() Reverses the order of the elements of list lst in place.
list(reversed(lst)) The built-in reversed(lst) method creates a new list object with reversed list elements.
lst[::-1] Slicing with negative indexing is the most concise way of reversing the order of a list. It creates a new list object.
[lst[i] for i in range(len(lst)-1,-1,-1)] Just for fun—one-liner solution to reverse a list using list comprehension and the negative range function.

There is a fifth solution using recursion. But it’s highly inefficient and you shouldn’t use it in practice. If you want to learn about it anyways, read on. But don’t tell me you haven’t been warned!

Python List Reverse Recursive

You can create a recursive function to reverse any list. I’ll give you the code first and explain it later:

>>> reverse = lambda lst: reverse(lst[1:]) + [lst[0]] if lst else []

Let’s check if it does what it’s supposed to do (reversing the list):

>>> reverse([1, 2, 3])
[3, 2, 1]
>>> reverse(["Ann", 1, 42, 0])
[0, 42, 1, 'Ann']
>>> reverse([])
[]
>>> reverse([1])
[1]

Okay, it works!

The recursive one-liner solution uses several Python features you have to understand before you can understand it entirely:

Phew! Quite some information to digest! But that’s not all. If you’ve understood all of the above, you also need to understand recursion. That’s too much to teach in a single paragraph so I’d send you over to my blog article about recursion.

I’ll say only that much: to understand recursion, you first need to understand recursion! 😉

Python List Reverse Slice

Slicing is the easiest way to reverse a list.

To reverse the list lst, you simply use slicing operation lst[::-1] with default start and stop indices (not given) and negative step size -1 (given).

There’s only one case where you shouldn’t use slicing to reverse the list and this is if you don’t want to create a new list. In this case, stick to the lst.reverse() method which reverses the list in place.

Here’s an example of slicing to reverse a given list:

>>> friends = ["Ann", "Carsten", "Bob", "Alice"]
>>> r_friends = friends[::-1]
>>> friends
['Ann', 'Carsten', 'Bob', 'Alice']
>>> r_friends
['Alice', 'Bob', 'Carsten', 'Ann']

You see that the two lists friends and r_friends are independent objects in memory because the slicing operation creates a new list.

Related articles:

Python List Reverse Copy

There are two ways to copy a list and reverse the order of its elements:

  • Use slicing list[::-1], or
  • Call the reversed(list) method and convert the result to a list using the list(...) constructor.

Here are both in action:

>>> lst_1 = ['Alice', 'Bob', 'Ann']
>>> lst_2 = lst_1[::-1]
>>> lst_3 = list(reversed(lst_1))
>>> lst_1
['Alice', 'Bob', 'Ann']
>>> lst_2
['Ann', 'Bob', 'Alice']
>>> lst_3
['Ann', 'Bob', 'Alice']

Python List Partial Reverse

To partially reverse a list lst, use slicing with negative step size: lst[start:stop:-1]. The start and stop values define the part of the list to be reversed and the step size -1 means that you go through the list in reversed order.

Here’s an example of some partial list reversals:

>>> lst = ['a', 'b', 'c', 'd', 'e']
>>> lst[5:2:-1]
['e', 'd']
>>> lst[:1:-1]
['e', 'd', 'c']
>>> lst[3:2:-1]
['d']

All of those slicing operations reversed a subsequence of the original list. Note that the start index must be larger or equal than the stop index because you traverse the list in negative order (well, if you don’t want to have an empty slice object).

Python List Reverse List Comprehension

You can reverse a list with Python’s powerful list comprehension method. (Although I cannot imagine a scenario where this would actually make sense.)

Related article:

List comprehension is a compact way of creating lists. The simple formula is [ expression + context ].

  • Expression: What to do with each list element?
  • Context: What list elements to select? It consists of an arbitrary number of for and if statements.

For example, the expression [x for x in range(3)] creates the list [0, 1, 2].

Here’s how you’d use list comprehension to reverse a list:

[lst[i] for i in range(len(lst)-1,-1,-1)]

You go over all indices in negative order—starting with the last list index len(lst)-1 and ending in the first list index 0. Note that the stop index is not included in the index sequence so I used the value -1 as the stop index for the range() built-in function.

Python List reverse() vs reversed()

What’s the difference between the method list.reverse() and the built-in function reversed(list)?

  • list.reverse() modifies an existing list in place and reverses the order of elements in this list object. No new list object is created.
  • reversed(list) creates a new iterable object by reversing the order of elements of the original list.

So you should use the former if you don’t want to create a new list and the latter if you want to create a new iterable without modifying the existing list.

An example is the following:

>>> lst_1 = [1, 2, 3]
>>> lst_1.reverse()
>>> lst_1
[3, 2, 1]
>>> reversed(lst_1)
<list_reverseiterator object at 0x0000025B58FEC9B0>

The output is not very intuitive but it only means that the reversed() function returns an iterable object.

Python List Deep Reverse

What if you want not only to reverse a list but running a deep reverse where all nested lists are also reversed in a recursive manner?

Here’s how you can do it:

def deep_reverse(lst): ''' Reverses a nested list in place''' # Reverse top-level list lst.reverse() # Recursively reverse all nested lists for element in lst: if isinstance(element, list): deep_reverse(element) lst = [1, 2, 3, [4, 5, 6]]
deep_reverse(lst)
print(lst)

This generates the output:

# OUTPUT: [[6, 5, 4], 3, 2, 1]

Not only the first-level list is reversed but also the second-level list. The code is loosely inspired from this article.

Python List Reverse Enumerate

The enumerate(list) built-in function returns a list of tuples with the first tuple value being the list index and the second tuple value being the list element.

You can reverse the order of enumerated tuples by stacking together the enumerate() function and the list.reverse() method as follows:

>>> for i, el in enumerate(list(reversed([1, 2, 3]))): print(i, el) 0 3
1 2
2 1

This way, you first reverse the list which creates an iterator. You then transform it into a list. The result can be enumerated.

If you want to reverse the order of the indices as well, simply switch the order of both functions:

>>> for i, el in reversed(list(enumerate([1, 2, 3]))): print(i, el) 2 3
1 2
0 1

By first enumerating, you calculate the indices based on the original list. Then you reverse them in the outer function.

Python List Reverse Iterator

The reversed(list) method returns an iterator, not a new list. This is different: an iterator is more efficient than a list. You can easily convert the iterator object into a list by using the list(...) built-in function.

Here’s an example:

>>> reversed([1, 2, 3])
<list_reverseiterator object at 0x0000021735E070B8>
>>> for i in reversed([1, 2, 3]): print(i) 3
2
1

The iterator object doesn’t look pretty in the shell but it’s a more efficient way to iterate over a sequence of values than using lists. Why? Because lists need to maintain all values in memory. Iterators don’t.

Python List Reverse Sort

Do you want to sort a list in descending order? Use the reverse=True argument of the sorted() method. Here’s an example:

>>> sorted([42, 1, 99])
[1, 42, 99]
>>> sorted([42, 1, 99], reverse=True)
[99, 42, 1]

Python List reverse() Index

Rather than just using positive list indices, you can use reverse indexing in Python lists, too. The negative integer index -1 accesses the last element. The negative integer index -2 accesses the second last element and so on. Here’s an example:

>>> lst = ["Alice", "Bob", "Ann"]
>>> lst[-1] 'Ann'
>>> lst[-2] 'Bob'
>>> lst[-3] 'Alice'

Python List Reverse range()

Do you want to iterate over a range of integer values in reverse order? Say, you want to iterate over the numbers from 10 to 0 in reverse order: 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0. You can simply achieve this by specifying the start, stop, and step arguments of the range(start, stop, step) method:

>>> for i in range(10, -1, -1): print(i) 10
9
8
7
6
5
4
3
2
1
0

Note that the start argument is included in the range but the stop argument isn’t.

Python List reverse() Doesn’t Work

What if the reverse() method doesn’t work? Chances are that you assume the list.reverse() method has a return value—that is the reversed list. This is not the case! The list.reverse() method returns None because it reverses the list in place. It doesn’t return a new reversed list.

Here’s an example what you’re probably doing:

>>> lst = [1, 2, 3]
>>> print(lst)
[1, 2, 3]
>>> print(lst.reverse())
None

If you really want to have a new list with elements in reversed order, use the Python built-in reversed(list) method:

>>> print(list(reversed([1, 2, 3])))
[3, 2, 1]

The reversed() method reverses the list and returns the reversed list as an iterator object. You need to convert it to a list first before printing it to the shell (and receiving a meaningful output).

Python Reverse List NumPy

To reverse a NumPy array (or even a Python list), you can simply use slicing with negative step size a[::-1]. Here’s an example:

>>> import numpy as np
>>> a = np.array([1, 2, 3])
>>> a[::-1]
array([3, 2, 1])

Python List reverse() Thread Safe

Do you have a multiple threads that access your list at the same time? Then you need to be sure that the list operations (such as reverse()) are actually thread safe.

In other words: can you call the reverse() operation in two threads on the same list at the same time? (And can you be sure that the result is meaningful?)

The answer is yes (if you use the cPython implementation). The reason is Python’s global interpreter lock that ensures that a thread that’s currently working on it’s code will first finish its current basic Python operation as defined by the cPython implementation. Only if it terminates with this operation will the next thread be able to access the computational resource. This is ensured with a sophisticated locking scheme by the cPython implementation.

The only thing you need to know is that each basic operation in the cPython implementation is atomic. It’s executed wholly and at once before any other thread has the chance to run on the same virtual engine. Therefore, there are no race conditions. An example for such a race condition would be the following: the first thread reads a value from the list, the second threads overwrites the value, and the first thread overwrites the value again invalidating the second thread’s operation.

All cPython operations are thread-safe. But if you combine those operations into higher-level functions, those are not generally thread safe as they consist of many (possibly interleaving) operations.

Where to Go From Here?

The list.reverse() method reverses the order of the list elements.

You’ve learned the ins and outs of this important Python list method.

If you keep struggling with those basic Python commands and you feel stuck in your learning progress, I’ve got something for you: Python One-Liners (Amazon Link).

In the book, I’ll give you a thorough overview of critical computer science topics such as machine learning, regular expression, data science, NumPy, and Python basics—all in a single line of Python code!

Get the book from Amazon!

OFFICIAL BOOK DESCRIPTION: Python One-Liners will show readers how to perform useful tasks with one line of Python code. Following a brief Python refresher, the book covers essential advanced topics like slicing, list comprehension, broadcasting, lambda functions, algorithms, regular expressions, neural networks, logistic regression and more. Each of the 50 book sections introduces a problem to solve, walks the reader through the skills necessary to solve that problem, then provides a concise one-liner Python solution with a detailed explanation.

Posted on Leave a comment

How to Get the Key with Maximum Value in a Python Dictionary?

I have spent my morning hours on an important mission. What is the cleanest, fastest, and most concise answer to the following question: How do you find the key with the maximum value in a Python dictionary?  Most answers on the web say you need to use a library but this is not true!

Simply use the max function with the key argument set to dict.get:

income = {'Anne' : 1111, 'Bert' : 2222, 'Cara' : 9999999} print(max(income, key=income.get))
# Cara

The max function goes over all keys, k, in the dictionary income and takes the one that has maximum value after applying the income.get(k) method. The get() method returns the value specified for key, k, in the dictionary.

Play with it yourself in our interactive code shell:

Now, read the 4-min article or watch the short video to fully understand this concept.

What’s the Max Function in Python?

Most likely, you already know Python’s max(…) function. You can use it to find the maximum value of any iterable or any number of values. Here are a few examples using the max function without specifying any optional arguments.

# Key that starts with 'largest' letter of the alphabet
print(max(income))
# Mary # Largest value in the dictionary income
print(max(income.values()))
# 878000 # Largest value in the given list
print(max([1,4,7,5,3,99,3]))
# 99 # Compare lists element wise, max is first list to have a larger
# element print(max([1,2,3],[5,6,4]))
# [5, 6, 4] # Largest value in the given sequence of numbers
print(max(5,7,99,88,123))
# 123

So far so good. The max function is very flexible. It works not only for numbers but also for strings, lists, and any other object you can compare against other objects.

Now, let’s look at the optional arguments of the max function. One of them is 'key'. Let’s find out what it does.

How Does the Key Argument of Python’s max() Function Work?

The last examples show the intuitive workings of the max function: you pass one or more iterables as positional arguments.


Intermezzo: What are iterables? An iterable is an object from which you can get an iterator. An iterator is an object on which you can call the next() method. Each time you call next(), you get the ‘next’ element until you’ve got all the elements from the iterator. For example, Python uses iterators in for loops to go over all elements of a list, all characters of a string, or all keys in a dictionary.


When you specify the key argument, define a function that returns a value for each element of the iterable. Then each element is compared based on the return value of this function, not the iterable element (the default behavior).

Here is an example:

lst = [2, 4, 8, 16] def inverse(val): return -val print(max(lst))
# 16 print(max(lst, key=inverse))
# 2

We define a function inverse() that returns the value multiplied by -1. Now, we print two executions of the max() function. The first is the default execution: the maximum of the list [2, 4, 8, 16] is 16. The second uses key. We specify ‘inverse’ as the key function. Python applies this function to all values of [2, 4, 8, 16]. It compares these new values with each other and returns the max. Using the inverse function Python does the following mappings:

Original Value  Value after inverse() applied (basis for max())
2 -2
4 -4
8 -8
16 -16

Python calculates the maximum based on these mappings. In this case, the value 2 (with mapping -2) is the maximum value because -2 > -4 > -8 > -16. 

Now let’s come back to the initial question:

How to Get the Key with the Maximum Value in a Dictionary?

We use the same example as above. The dictionary stores the income of three persons John, Mary, and Alice. Suppose you want to find the person with the highest income. In other words, what is the key with the maximum value in the dictionary?

Now don’t confuse the dictionary key with the optional key argument of the max() function. They have nothing in common – it’s just an unfortunate coincidence that they have the same name!

From the problem, we know the result is a dictionary key. So, we call max() on the keys of the dictionary. Note that max(income.keys()) is the same as max(income). To learn more about dictionaries, check out our article Python Dictionary – The Ultimate Guide.

However, we want to compare dictionary values, not keys. We’ll use the key argument of max() to do this. We must pass it a function but which? 

To get the value of 'Anne', we can use bracket notation – income['Anne']. But bracket notation is not a function, so that doesn’t work. Fortunately, income.get(‘Anne’) does (almost) the same as income['Anne'] and it is a function! The only difference is that it returns None if they key is not in the dictionary. So we’ll pass that to the key argument of max().

income = {'Anne' : 1111, 'Bert' : 2222, 'Cara' : 9999999} print(max(income, key=income.get))
# Cara

How to Get the Key with the Minimum Value in a Dictionary?

If you understood the previous code snippet, this one will be easy. To find the key with minimum value in the dictionary we use the min() function.

income = {'Anne' : 1111, 'Bert' : 2222, 'Cara' : 9999999} print(min(income, key=income.get))
# Anne

The only difference is that we use the built-in min() function instead of the built-in max() function. That’s it.

Find the Key with the Max Value in a Dictionary – Alternative Methods

There are lots of different ways to solve this problem. They are not as beautiful or clean as the above method. But, for completeness, let’s explore some more ways of achieving the same thing.

In a StackOverflow answer, a user compared nine (!) different methods to find the key with the maximum value in a dictionary. Here they are:

# Convert to lists and use .index(max())
def f1(): v=list(income.values()) k=list(income.keys()) return k[v.index(max(v))] # Dictionary comprehension to swap keys and values
def f2(): d3={v:k for k,v in income.items()} return d3[max(d3)] # Use filter() and a lambda function
def f3(): return list(filter(lambda t: t[1]==max(income.values()), income.items()))[0][0] # Same as f3() but more explicit
def f4(): m=max(income.values()) return list(filter(lambda t: t[1]==m, income.items()))[0][0] # List comprehension
def f5(): return [k for k,v in income.items() if v==max(income.values())][0] # same as f5 but remove the max from the comprehension
def f6(): m=max(income.values()) return [k for k,v in income.items() if v==m][0] # Method used in this article
def f7(): return max(income,key=income.get) # Similar to f1() but shortened to 2 lines
def f8(): v=list(income.values()) return list(income.keys())[v.index(max(v))] # Similar to f7() but use a lambda function
def f9(): return max(income, key=lambda k: income[k]) print(f1())
print(f2())
print(f3())
print(f4())
print(f5())
print(f6())
print(f7())
print(f8())
print(f9())
# Cara (all outputs)

In a benchmark performed on a large dictionary by the StackOverflow user, f1() turned out to be the fastest one.

So the second best way to get the key with the maximum value from a dictionary is:

income = {'Anne' : 1111, 'Bert' : 2222, 'Cara' : 9999999} v=list(income.values())
k=list(income.keys())
print(k[v.index(max(v))])
# Cara

Find Key with Longest Value in Dictionary

We know how to find the maximum value if the values are numbers. What about if they are lists or strings?

Let’s say we have a dictionary that records the number of days each person worked this month. If they worked a day, we append 1 to that person’s list. If they didn’t work, we don’t do anything.  At the end of the month, our dictionary looks like this.

days_worked = {'Anne': [1, 1, 1, 1], 'Bert': [1, 1, 1, 1, 1, 1], 'Cara': [1, 1, 1, 1, 1, 1, 1, 1]}

The total number of days worked each month is the length of each list. If all elements of two lists are the same (as is the case here), they are compared based on their length.

# Length 2 is less than length 4
>>> [1, 1] < [1, 1, 1, 1]
True

So we can use the same code we’ve been using in the article to find the key with the maximum value.

>>> max(days_worked, key=days_worked.get) 'Cara'

If we update our dictionary so that Bert has worked the most days and apply max() again, Python returns ‘Bert’.

>>> days_worked = {'Anne': [1, 1, 1, 1], 'Bert': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 'Cara': [1, 1, 1, 1, 1, 1, 1, 1]} # Bert has now worked the most
>>> max(days_worked, key=days_worked.get)

Find Key With Max Value in a List of Dictionaries

Let’s say we have 3 dictionaries containing income information. We want to find the key with the max value from all 3 dictionaries. 

income1 = {'Anne': 1111, 'Bert': 2222, 'Cara': 3333} income2 = {'Dani': 4444, 'Ella': 5555, 'Fred': 6666} income3 = {'Greg': 7777, 'Hope': 8888, 'Igor': 999999999999} list_of_dicts = [income1, income2, income3]

We can see that ‘Igor’ has the highest income so we expect that to be returned.

There are several ways to do this. The simplest is to put all key-value pairs into one dictionary using a for loop. Then we call max() as usual.

# Initialise empty dict
>>> big_dict = {} # Use for loop and .update() method to add the key-value pairs
>>> for dic in list_of_dicts: big_dict.update(dic) # Check the result is as expected
>>> big_dict
{'Anne': 1111, 'Bert': 2222, 'Cara': 3333, 'Dani': 4444, 'Ella': 5555, 'Fred': 6666, 'Greg': 7777, 'Hope': 8888, 'Igor': 999999999999} # Call max() and specify key argument
>>> max(big_dict, key=big_dict.get) 'Igor' 

Where to Go From Here?

Every Python master must know the basics. Improving your basic code understanding skills by 20% will improve your productivity by much more than anything else. Why? Because everything else builds upon the basics.

But most material online is tedious and boring. That’s why I’ve written a new and exciting way of learning Python, while measuring and comparing your skills against other coders. Check out the book “Coffee Break Python”. It’s LeanPub 2019 bestseller in the category Python!

Posted on Leave a comment

Coding Doctor Against COVID-19

COVID-19 is everywhere. In this article, I want to express my deep gratitude for the doctors, nurses, and medical personnel working 70-hours or more per week to mitigate the adverse effects of the virus.

Here’s a pic of Finxter user Albrecht, a “retired” medical doctor supporting a COVID-19 test station in Germany:

Image

I asked the Finxter community to show Albrecht some support and encourage him in his fight against COVID-19.

Encouragements

Because the response has been huge, I decided to write this short blog article to collect some of the responses.

God Bless You

Dear Albrecht,
This is Anugraha from India. I really appreciate what you are doing for us. I will pray to my Lord and Saviour Jesus Christ that you be protected from the virus and that the people under your care and the care of doctors worldwide recover. I salute you and respect you. Men like you are the reason I want to become a doctor. God will honour you and bless you.

Anugraha

High Fives

HIGH Fives to all the people giving time to help their community! 😀

The Southland’s News Leader

Thanks

Thanks to Albrecht from our side!

Wajid

Desire to Help

Hello Doctor,
I do believe that no amount of money would drive you to offer this service. It can only be in the desire to help humanity. I wish I could do the same, but I surely can’t.
Bravo!
Halliday Johnson
Finxter user

Medicine to Immunity

If you want to take my suggestion then first make the medicine to increase high immunity power of people then only the search for the Corona treatment…… thanks for taking advice from me …

Charchit

Thanks for Fighting

Dear Albrecht,

Thank you for being there to help us fight CoronaVirus.I am from India and appreciate your support.

Kind regards,

Anil Rajpal

Real Hero

Hey Albrecht,

Thank You very much. People like you are the real heroes of our world. We are very grateful and thankful of you all the doctors who are helping us to fight back this Virus. I know we are from continents still this feeling to fight and win over this virus is mutual. We are all praying for you. Thank you again, stay safe and stay strong. GOD Bless YOU

Praju

You Rock

To Albrecht –  I am so appreciative of your work. You rock!! Karen Calhoun.

Danke

Danke dir Albrecht 👁👄👁

Joan

Stay Strong

Thank you for fighting against this covid-19 and risking your lives for others. Thank you for all the doctors and people who are contributing to save us thank you all… 
Stay safe. Stay strong.. Thank you.👏👏👏

Rutika

Thanks 4 All

Thanks Albrecht for all that you are doing!!!

Jim

Respect

Dear Albrecht
With great due respect, all the very best and may God bless you with the health and happiness and long life. Bravo to your friends and family. 
Regards, Rajender 

Go

Go Albrecht go!

Pierre

UK Should Do More

Hi from the UK,

my wishes go to Albrecht’s medical team. They are in luck—at least they have PPE (clothing) unlike NHS in UK who don’t as it is conveniently held up in a logistics mess up.
Meanwhile celebs in UK have been busy buying testing equipment at £385 each whereas our front line nurses and doctors don’t have access to such tests.
Other than that we are hoping that our UK government is mysteriously taken ill with some unknown illness as they are behaving in an appalling way to British Public.
Finally our schools are closing BUT not until next Monday
Wishing Europe all the best 
Oh we were once a part of that amazing place until a corrupt band took over our government and highjacked our press with such  wonderful newspapers full of intelligent writings such as Mail and Sun!!!
Keep up Pythoning!!
Regards Nigel

Hats Off

My heartfelt thanks and regards to all the Doctors. We are very grateful for your contributions especially during these unprecedented events.
May God bless You. 
Hats off to you all. 
Many Thanks.
Gia

With such a great support, I’m sure Albrecht is not going to stop soon. 😉

Albrecht’s Response

Here’s an idea from Albrecht:


Great! I thank you so much!  

Interesting site dealing with the math structure of epidemy:   https://www.washingtonpost.com/graphics/2020/health/corona-simulator-german/?utm_source=pocket-newtab  

How could we reproduce this in Python code?    

Albrecht


So how can you help fighting COVID-19?

  • Participate in hackathons! Here’s an example from the German government initiated: https://wirvsvirushackathon.org/. Those hackathons start all over the world.
  • Be creative with your Python skills! Consider Albrecht’s question: How could we reproduce [the mathematical side of the outbreak] in Python code? Start your new coding projects now that solve real-world problems that arise because of COVID-19.
  • Code from home! (And reduce your physical contacts by half.) This mitigates the spread of the disease, keeps the health system intact, and helps the environment too.
Posted on Leave a comment

Python Regex Quantifiers – Question Mark (?) vs Plus (+) vs Asterisk (*)

In this tutorial, I’ll show you the difference of the regular expression quantifiers in Python.

What’s the difference between the question mark quantifier (?), the plus quantifier (+), and the asterisk quantifier (*)?

Say, you have regular expression pattern A.

  • Regex A? matches zero or one occurrences of A.
  • Regex A* matches zero or more occurrences of A.
  • Regex A+ matches one or more occurrences of A.

Try it yourself:

Asterisk vs Question Mark

You can read the Python Re A? quantifier as zero-or-one regex: the preceding regex A is matched either zero times or exactly once. But it’s not matched more often.

Analogously, you can read the Python Re A* operator as the zero-or-more regex (I know it sounds a bit clunky): the preceding regex A is matched an arbitrary number of times.

Here’s an example that shows the difference:

>>> import re
>>> re.findall('ab?', 'abbbbbbb')
['ab']
>>> re.findall('ab*', 'abbbbbbb')
['abbbbbbb']

The regex ‘ab?’ matches the character ‘a’ in the string, followed by character ‘b’ if it exists (which it does in the code).

The regex ‘ab*’ matches the character ‘a’ in the string, followed by as many characters ‘b’ as possible.

Asterisk vs Plus

You can read the Python Re A* quantifier as zero-or-more regex: the preceding regex A is matched an arbitrary number of times.

Analogously, you can read the Python Re A+ operator as the at-least-once regex: the preceding regex A is matched an arbitrary number of times too—but at least once.

Here’s an example that shows the difference:

>>> import re
>>> re.findall('ab*', 'aaaaaaaa')
['a', 'a', 'a', 'a', 'a', 'a', 'a', 'a']
>>> re.findall('ab+', 'aaaaaaaa')
[]

The regex ‘ab*’ matches the character ‘a’ in the string, followed by an arbitary number of occurrences of character ‘b’. The substring ‘a’ perfectly matches this formulation. Therefore, you find that the regex matches eight times in the string.

The regex ‘ab+’ matches the character ‘a’, followed by as many characters ‘b’ as possible—but at least one. However, the character ‘b’ does not exist so there’s no match.

Summary: When applied to regular expression A, Python’s A* quantifier matches zero or more occurrences of A. The * quantifier is called asterisk operator and it always applies only to the preceding regular expression. For example, the regular expression ‘yes*’ matches strings ‘ye’, ‘yes’, and ‘yesssssss’. But it does not match the empty string because the asterisk quantifier * does not apply to the whole regex ‘yes’ but only to the preceding regex ‘s’.

Question Mark vs Plus

You can read the Python Re A? quantifier as zero-or-one regex: the preceding regex A is matched either zero times or exactly once. But it’s not matched more often.

Analogously, you can read the Python Re A+ operator as the at-least-once regex: the preceding regex A is matched an arbitrary number of times but at least once.

Here’s an example that shows the difference:

>>> import re
>>> re.findall('ab?', 'aaaaaaaa')
['a', 'a', 'a', 'a', 'a', 'a', 'a', 'a']
>>> re.findall('ab+', 'aaaaaaaa')
[]

The regex ‘ab?’ matches the character ‘a’ in the string, followed by character ‘b’ if it exists—but it doesn’t in the code.

The regex ‘ab+’ matches the character ‘a’ in the string, followed by as many characters ‘b’ as possible—but at least one. However, the character ‘b’ does not exist so there’s no match.

Where to Go From Here?

You’ve learned the difference of the regex quantifiers in Python.

Summary: Regex A? matches zero or one occurrences of A. Regex A* matches zero or more occurrences of A. Regex A+ matches one or more occurrences of A.

Want to earn money while you learn Python? Average Python programmers earn more than $50 per hour. You can become average, can’t you?

Join the free webinar that shows you how to become a thriving coding business owner online!

[Webinar] Are You a Six-Figure Freelance Developer?

Join us. It’s fun! 🙂

Posted on Leave a comment

Python List reverse()

This tutorial shows you everything you need to know to help you master the essential reverse() method of the most fundamental container data type in the Python programming language.

Definition and Usage:

The list.reverse() reverses the order of the elements in the list. If you want to create a new list with reversed elements, use slicing with negative step size list[::-1].

Here’s a short example:

>>> lst = [1, 2, 3, 4]
>>> lst.reverse()
>>> lst
[4, 3, 2, 1]

In the first line of the example, you create the list lst. You then reverse the order of the elements in the list and print it to the shell.

Code Puzzle — Try It Yourself:

Now you know the basics. Let’s deepen your understanding with a short code puzzle—can you solve it?

You can also solve this puzzle and track your Python skills on our interactive Finxter app.

Syntax: You can call this method on each list object in Python. Here’s the syntax:

list.reverse()

Arguments: The reverse method doesn’t take any arguments.

Return value: The method list.reverse() has return value None. It reverses the elements of the list in place (but doesn’t create a new list). Thus, a return value is not needed.

Python List reverse() Time Complexity

The time complexity of the reverse() operation is O(n) for a list with n elements. The standard Python implementation cPython “touches” all elements in the original list to move them to another position. Thus, the time complexity is linear in the number of list elements.

You can see a plot of the time complexity of the reverse() method for growing list size here:

Time complexity of Python List reverse()

The figure shows how the elapsed time of reversing lists with growing number of elements grows linear to the number of elements.

If you’re interested in the code I used to generate this plot with Matplotlib, this is it:

import matplotlib.pyplot as plt
import time y = []
for i in [100000 * j for j in range(10,100)]: lst = list(range(i)) t0 = time.time() x = lst.reverse() t1 = time.time() y.append(t1-t0) plt.plot(y)
plt.xlabel("List elements (10**5)")
plt.ylabel("Time (sec)")
plt.show()

Python List reverse() In Place

If you call the list.reverse() method on any list object in Python, it reverses the list elements of this particular list object. You say that the reverse method happens in place.

This is a common mistake of many Python beginners. They assume that the reverse() method creates a new list with the elements in reversed order. This is not the case: the reverse() method modifies only the existing list object.

You can see this in the following example:

>>> lst = [1, 2, 3]
>>> lst.reverse()
>>> lst
[3, 2, 1]

In the example, you only reversed the existing list lst. But you didn’t create a new list!

Python List reverse() None

The return value of the list.reverse() method is None. Why? Because the method reverses the list in place. This means that no new list is created. Instead, the method modifies the old list object.

You’ve seen an example of this in the previous section.

Python List Reverse List Without reverse()

You can also reverse a list without using the reverse() method. Let’s have a look at the following table that shows all reverse() alternatives:

Method Description
lst.reverse() Reverses the order of the elements of list lst in place.
list(reversed(lst)) The built-in reversed(lst) method creates a new list object with reversed list elements.
lst[::-1] Slicing with negative indexing is the most concise way of reversing the order of a list. It creates a new list object.
[lst[i] for i in range(len(lst)-1,-1,-1)] Just for fun—one-liner solution to reverse a list using list comprehension and the negative range function.

There is a fifth solution using recursion. But it’s highly inefficient and you shouldn’t use it in practice. If you want to learn about it anyways, read on. But don’t tell me you haven’t been warned!

Python List Reverse Recursive

You can create a recursive function to reverse any list. I’ll give you the code first and explain it later:

>>> reverse = lambda lst: reverse(lst[1:]) + [lst[0]] if lst else []

Let’s check if it does what it’s supposed to do (reversing the list):

>>> reverse([1, 2, 3])
[3, 2, 1]
>>> reverse(["Ann", 1, 42, 0])
[0, 42, 1, 'Ann']
>>> reverse([])
[]
>>> reverse([1])
[1]

Okay, it works!

The recursive one-liner solution uses several Python features you have to understand before you can understand it entirely:

Phew! Quite some information to digest! But that’s not all. If you’ve understood all of the above, you also need to understand recursion. That’s too much to teach in a single paragraph so I’d send you over to my blog article about recursion.

I’ll say only that much: to understand recursion, you first need to understand recursion! 😉

Python List Reverse Slice

Slicing is the easiest way to reverse a list.

To reverse the list lst, you simply use slicing operation lst[::-1] with default start and stop indices (not given) and negative step size -1 (given).

There’s only one case where you shouldn’t use slicing to reverse the list and this is if you don’t want to create a new list. In this case, stick to the lst.reverse() method which reverses the list in place.

Here’s an example of slicing to reverse a given list:

>>> friends = ["Ann", "Carsten", "Bob", "Alice"]
>>> r_friends = friends[::-1]
>>> friends
['Ann', 'Carsten', 'Bob', 'Alice']
>>> r_friends
['Alice', 'Bob', 'Carsten', 'Ann']

You see that the two lists friends and r_friends are independent objects in memory because the slicing operation creates a new list.

Related articles:

Python List Reverse Copy

There are two ways to copy a list and reverse the order of its elements:

  • Use slicing list[::-1], or
  • Call the reversed(list) method and convert the result to a list using the list(...) constructor.

Here are both in action:

>>> lst_1 = ['Alice', 'Bob', 'Ann']
>>> lst_2 = lst_1[::-1]
>>> lst_3 = list(reversed(lst_1))
>>> lst_1
['Alice', 'Bob', 'Ann']
>>> lst_2
['Ann', 'Bob', 'Alice']
>>> lst_3
['Ann', 'Bob', 'Alice']

Python List Partial Reverse

To partially reverse a list lst, use slicing with negative step size: lst[start:stop:-1]. The start and stop values define the part of the list to be reversed and the step size -1 means that you go through the list in reversed order.

Here’s an example of some partial list reversals:

>>> lst = ['a', 'b', 'c', 'd', 'e']
>>> lst[5:2:-1]
['e', 'd']
>>> lst[:1:-1]
['e', 'd', 'c']
>>> lst[3:2:-1]
['d']

All of those slicing operations reversed a subsequence of the original list. Note that the start index must be larger or equal than the stop index because you traverse the list in negative order (well, if you don’t want to have an empty slice object).

Python List Reverse List Comprehension

You can reverse a list with Python’s powerful list comprehension method. (Although I cannot imagine a scenario where this would actually make sense.)

Related article:

List comprehension is a compact way of creating lists. The simple formula is [ expression + context ].

  • Expression: What to do with each list element?
  • Context: What list elements to select? It consists of an arbitrary number of for and if statements.

For example, the expression [x for x in range(3)] creates the list [0, 1, 2].

Here’s how you’d use list comprehension to reverse a list:

[lst[i] for i in range(len(lst)-1,-1,-1)]

You go over all indices in negative order—starting with the last list index len(lst)-1 and ending in the first list index 0. Note that the stop index is not included in the index sequence so I used the value -1 as the stop index for the range() built-in function.

Python List reverse() vs reversed()

What’s the difference between the method list.reverse() and the built-in function reversed(list)?

  • list.reverse() modifies an existing list in place and reverses the order of elements in this list object. No new list object is created.
  • reversed(list) creates a new iterable object by reversing the order of elements of the original list.

So you should use the former if you don’t want to create a new list and the latter if you want to create a new iterable without modifying the existing list.

An example is the following:

>>> lst_1 = [1, 2, 3]
>>> lst_1.reverse()
>>> lst_1
[3, 2, 1]
>>> reversed(lst_1)
<list_reverseiterator object at 0x0000025B58FEC9B0>

The output is not very intuitive but it only means that the reversed() function returns an iterable object.

Python List Deep Reverse

What if you want not only to reverse a list but running a deep reverse where all nested lists are also reversed in a recursive manner?

Here’s how you can do it:

def deep_reverse(lst): ''' Reverses a nested list in place''' # Reverse top-level list lst.reverse() # Recursively reverse all nested lists for element in lst: if isinstance(element, list): deep_reverse(element) lst = [1, 2, 3, [4, 5, 6]]
deep_reverse(lst)
print(lst)

This generates the output:

# OUTPUT: [[6, 5, 4], 3, 2, 1]

Not only the first-level list is reversed but also the second-level list. The code is loosely inspired from this article.

Python List Reverse Enumerate

The enumerate(list) built-in function returns a list of tuples with the first tuple value being the list index and the second tuple value being the list element.

You can reverse the order of enumerated tuples by stacking together the enumerate() function and the list.reverse() method as follows:

>>> for i, el in enumerate(list(reversed([1, 2, 3]))): print(i, el) 0 3
1 2
2 1

This way, you first reverse the list which creates an iterator. You then transform it into a list. The result can be enumerated.

If you want to reverse the order of the indices as well, simply switch the order of both functions:

>>> for i, el in reversed(list(enumerate([1, 2, 3]))): print(i, el) 2 3
1 2
0 1

By first enumerating, you calculate the indices based on the original list. Then you reverse them in the outer function.

Python List Reverse Iterator

The reversed(list) method returns an iterator, not a new list. This is different: an iterator is more efficient than a list. You can easily convert the iterator object into a list by using the list(...) built-in function.

Here’s an example:

>>> reversed([1, 2, 3])
<list_reverseiterator object at 0x0000021735E070B8>
>>> for i in reversed([1, 2, 3]): print(i) 3
2
1

The iterator object doesn’t look pretty in the shell but it’s a more efficient way to iterate over a sequence of values than using lists. Why? Because lists need to maintain all values in memory. Iterators don’t.

Python List Reverse Sort

Do you want to sort a list in descending order? Use the reverse=True argument of the sorted() method. Here’s an example:

>>> sorted([42, 1, 99])
[1, 42, 99]
>>> sorted([42, 1, 99], reverse=True)
[99, 42, 1]

Python List reverse() Index

Rather than just using positive list indices, you can use reverse indexing in Python lists, too. The negative integer index -1 accesses the last element. The negative integer index -2 accesses the second last element and so on. Here’s an example:

>>> lst = ["Alice", "Bob", "Ann"]
>>> lst[-1] 'Ann'
>>> lst[-2] 'Bob'
>>> lst[-3] 'Alice'

Python List Reverse range()

Do you want to iterate over a range of integer values in reverse order? Say, you want to iterate over the numbers from 10 to 0 in reverse order: 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0. You can simply achieve this by specifying the start, stop, and step arguments of the range(start, stop, step) method:

>>> for i in range(10, -1, -1): print(i) 10
9
8
7
6
5
4
3
2
1
0

Note that the start argument is included in the range but the stop argument isn’t.

Python List reverse() Doesn’t Work

What if the reverse() method doesn’t work? Chances are that you assume the list.reverse() method has a return value—that is the reversed list. This is not the case! The list.reverse() method returns None because it reverses the list in place. It doesn’t return a new reversed list.

Here’s an example what you’re probably doing:

>>> lst = [1, 2, 3]
>>> print(lst)
[1, 2, 3]
>>> print(lst.reverse())
None

If you really want to have a new list with elements in reversed order, use the Python built-in reversed(list) method:

>>> print(list(reversed([1, 2, 3])))
[3, 2, 1]

The reversed() method reverses the list and returns the reversed list as an iterator object. You need to convert it to a list first before printing it to the shell (and receiving a meaningful output).

Python Reverse List NumPy

To reverse a NumPy array (or even a Python list), you can simply use slicing with negative step size a[::-1]. Here’s an example:

>>> import numpy as np
>>> a = np.array([1, 2, 3])
>>> a[::-1]
array([3, 2, 1])

Python List reverse() Thread Safe

Do you have a multiple threads that access your list at the same time? Then you need to be sure that the list operations (such as reverse()) are actually thread safe.

In other words: can you call the reverse() operation in two threads on the same list at the same time? (And can you be sure that the result is meaningful?)

The answer is yes (if you use the cPython implementation). The reason is Python’s global interpreter lock that ensures that a thread that’s currently working on it’s code will first finish its current basic Python operation as defined by the cPython implementation. Only if it terminates with this operation will the next thread be able to access the computational resource. This is ensured with a sophisticated locking scheme by the cPython implementation.

The only thing you need to know is that each basic operation in the cPython implementation is atomic. It’s executed wholly and at once before any other thread has the chance to run on the same virtual engine. Therefore, there are no race conditions. An example for such a race condition would be the following: the first thread reads a value from the list, the second threads overwrites the value, and the first thread overwrites the value again invalidating the second thread’s operation.

All cPython operations are thread-safe. But if you combine those operations into higher-level functions, those are not generally thread safe as they consist of many (possibly interleaving) operations.

Where to Go From Here?

The list.reverse() method reverses the order of the list elements.

You’ve learned the ins and outs of this important Python list method.

If you keep struggling with those basic Python commands and you feel stuck in your learning progress, I’ve got something for you: Python One-Liners (Amazon Link).

In the book, I’ll give you a thorough overview of critical computer science topics such as machine learning, regular expression, data science, NumPy, and Python basics—all in a single line of Python code!

Get the book from Amazon!

OFFICIAL BOOK DESCRIPTION: Python One-Liners will show readers how to perform useful tasks with one line of Python code. Following a brief Python refresher, the book covers essential advanced topics like slicing, list comprehension, broadcasting, lambda functions, algorithms, regular expressions, neural networks, logistic regression and more. Each of the 50 book sections introduces a problem to solve, walks the reader through the skills necessary to solve that problem, then provides a concise one-liner Python solution with a detailed explanation.

Posted on Leave a comment

Python List pop()

This tutorial shows you everything you need to know to help you master the essential pop() method of the most fundamental container data type in the Python programming language.

Definition and Usage:

The list.pop() method removes and returns the last element from an existing list. The list.pop(index) method with the optional argument index removes and returns the element at the position index.

Here’s a short example:

>>> lst = [1, 2, 3]
>>> lst.pop()
3
>>> lst
[1, 2]

In the first line of the example, you create the list lst. You then remove and return the final element 3 from the list. The result is the list with only two elements [1, 2].

Code Puzzle — Try It Yourself:

Now you know the basics. Let’s deepen your understanding with a short code puzzle—can you solve it?

You can also solve this puzzle and track your Python skills on our interactive Finxter app.

Syntax:

You can call this method on each list object in Python. Here’s the syntax:

list.pop(index=-1)

Arguments:

Argument Description
index Optional argument. You can define the index of the element to be removed and returned. The default argument leads to the removal of the last list element with index -1.

Return value:

The method list.pop() has return value Object. It removes the respective element from the list (default: the last element) and returns it directly to the caller.

Video:

Python List pop() By Index

You can use the list.pop(index) method to with the optional index argument to remove and return the element at position index from the list.

Here’s an example:

>>> customers = ['Alice', 'Bob', 'Ann', 'Frank']
>>> customers.pop(2) 'Ann'
>>> customers
['Alice', 'Bob', 'Frank']
>>> customers.pop(0) 'Alice'
>>> customers
['Bob', 'Frank']

After creating the list with four elements, you first remove and return the second element 'Ann'. Then, you remove and return the first element 'Alice'. The resulting list has only two elements left.

Python List pop() First / Front / Left / Head

The list.pop(index) method to with the optional index argument to remove and return the element at position index from the list. So if you want to remove the first element from the list, simply set index=0 by calling list.pop(0). This will pop the first element from the list.

Here’s an example:

>>> primes = [1, 2, 3, 5, 7, 11]
>>> primes.pop(0)
1
>>> primes
[2, 3, 5, 7, 11]

The pop(0) method removes the first element 1 from the list of prime numbers given in the example.

Python List pop() By Value

In the previous two examples, you’ve seen how to pop elements by index. But can you also pop by value?

Yes, you can by using the list.index(value) method which gives you the index of the element value in the list. Now, you can use the list.pop(index) method on this index to remove the value from the list and get the result as a return value.

Here’s an example where you want to pop the element 7 from the list and store the result in the variable some_prime.

>>> primes = [1, 2, 3, 5, 7, 11]
>>> some_prime = primes.pop(primes.index(7))
>>> some_prime
7

If you’re not interested in the return value but you only want to remove the first occurrence of the value x in the list, use the list.remove(x) method.

Related Article:

Python List pop() Multiple Elements

Python List pop() First n Elements

Python List pop() Last n Elements

Python List pop() Time Complexity … First and Last and General cases

Python List pop() vs remove()

Python List Pop and Push (Stack)

Python List pop() Without Remove

Python List pop() While Iterating

Python List pop() If Not Empty

Python List pop() Slice

Alternatives Ways to Remove Elements From a List

There are some alternative ways to remove elements from the list. See the overview table:

Method Description
lst.remove(x) Remove an element from the list (by value)
lst.pop() Remove an element from the list (by index) and return the element
lst.clear() Remove all elements from the list
del lst[3] Remove one or more elements from the list (by index or slice)
List comprehension Remove all elements that meet a certain condition

Next, you’ll dive into each of those methods to gain some deep understanding.

remove() — Remove An Element by Value

To remove an element from the list, use the list.remove(element) method you’ve already seen previously:

>>> lst = ["Alice", 3, "alice", "Ann", 42]
>>> lst.remove("Ann")
>>> lst
['Alice', 3, 'alice', 42]

Try it yourself:

The method goes from left to right and removes the first occurrence of the element that’s equal to the one to be removed.

Removed Element Does Not Exist

If you’re trying to remove element x from the list but x does not exist in the list, Python throws a Value error:

>>> lst = ['Alice', 'Bob', 'Ann']
>>> lst.remove('Frank')
Traceback (most recent call last): File "<pyshell#19>", line 1, in <module> lst.remove('Frank')
ValueError: list.remove(x): x not in list

pop() — Remove An Element by Index

Per default, the pop() method removes the last element from the list and returns the element.

>>> lst = ['Alice', 'Bob', 'Ann']
>>> lst.pop() 'Ann'
>>> lst
['Alice', 'Bob']

But you can also define the optional index argument. In this case, you’ll remove the element at the given index—a little known Python secret!

>>> lst = ['Alice', 'Bob', 'Ann']
>>> lst.pop(1) 'Bob'
>>> lst
['Alice', 'Ann']

clear() — Remove All Elements

The clear() method simply removes all elements from a given list object.

>>> lst = ['Alice', 'Bob', 'Ann']
>>> lst.clear()
>>> lst
[]

del — Remove Elements by Index or Slice

This trick is also relatively unknown among Python beginners:

  • Use del lst[index] to remove the element at index.
  • Use del lst[start:stop] to remove all elements in the slice.
>>> lst = list(range(10))
>>> lst
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> del lst[5]
>>> lst
[0, 1, 2, 3, 4, 6, 7, 8, 9]
>>> del lst[:4]
>>> lst
[4, 6, 7, 8, 9]

Related blog articles:

List Comprehension — Remove Elements Conditionally

Okay, this is kind of cheating because this method does not really remove elements from a list object. It merely creates a new list with some elements that meet your condition.

List comprehension is a compact way of creating lists. The simple formula is [ expression + context ].

  • Expression: What to do with each list element?
  • Context: What list elements to select? It consists of an arbitrary number of for and if statements.

The example [x for x in range(3)] creates the list [0, 1, 2].

You can also define a condition such as all odd values x%2==1 in the context part by using an if condition. This leads us to a way to remove all elements that do not meet a certain condition in a given list.

>>> lst = list(range(10))
>>> lst_new = [x for x in lst if x%2]
>>> lst_new
[1, 3, 5, 7, 9] 

While you iterate over the whole list lst, the condition x%2 requires that the elements are odd.

Related blog articles:

Python List pop() Thread Safe

Do you have a multiple threads that access your list at the same time? Then you need to be sure that the list operations (such as pop()) are actually thread safe.

In other words: can you call the pop() operation in two threads on the same list at the same time? (And can you be sure that the result is meaningful?)

The answer is yes (if you use the cPython implementation). The reason is Python’s global interpreter lock that ensures that a thread that’s currently working on it’s code will first finish its current basic Python operation as defined by the cPython implementation. Only if it terminates with this operation will the next thread be able to access the computational resource. This is ensured with a sophisticated locking scheme by the cPython implementation.

The only thing you need to know is that each basic operation in the cPython implementation is atomic. It’s executed wholly and at once before any other thread has the chance to run on the same virtual engine. Therefore, there are no race conditions. An example for such a race condition would be the following: the first thread reads a value from the list, the second threads overwrites the value, and the first thread overwrites the value again invalidating the second thread’s operation.

All cPython operations are thread-safe. But if you combine those operations into higher-level functions, those are not generally thread safe as they consist of many (possibly interleaving) operations.

Where to Go From Here?

The list.remove(element) method removes the first occurrence of element from the list.

You’ve learned the ins and outs of this important Python list method.

If you keep struggling with those basic Python commands and you feel stuck in your learning progress, I’ve got something for you: Python One-Liners (Amazon Link).

In the book, I’ll give you a thorough overview of critical computer science topics such as machine learning, regular expression, data science, NumPy, and Python basics—all in a single line of Python code!

Get the book from Amazon!

OFFICIAL BOOK DESCRIPTION: Python One-Liners will show readers how to perform useful tasks with one line of Python code. Following a brief Python refresher, the book covers essential advanced topics like slicing, list comprehension, broadcasting, lambda functions, algorithms, regular expressions, neural networks, logistic regression and more. Each of the 50 book sections introduces a problem to solve, walks the reader through the skills necessary to solve that problem, then provides a concise one-liner Python solution with a detailed explanation.

Posted on Leave a comment

Python List copy()

Surprisingly, even advanced Python coders don’t know the details of the copy() method of Python lists. Time to change that!

Definition and Usage: The list.copy() method copies all list elements into a new list. The new list is the return value of the method. It’s a shallow copy—you copy only the object references to the list elements and not the objects themselves.

Here’s a short example:

>>> lst = [1, 2, 3]
>>> lst.copy()
[1, 2, 3]

In the first line, you create the list lst consisting of three integers. You then create a new list by copying all elements.

Puzzle – Try It Yourself:

Syntax: You can call this method on each list object in Python. Here’s the syntax:

list.copy()

Arguments: The method doesn’t take any argument.

Return value: The method list.clear() returns a list object by copying references to all objects in the original list.

Video:

Python List Copy Shallow

Before you can truly understand the copy() method in Python, you must understand the concept of a “shallow copy”.

In object-oriented languages such as Python, everything is an object. The list is an object and the elements in the list are objects, too. A shallow copy of the list creates a new list object—the copy—but it doesn’t create new list elements but simply copies the references to these objects.

You can see that the list below is only a shallow copy pointing to the same elements as the original list.

In Python, the list.copy() method only produces a shallow copy which has much faster runtime complexity.

Here’s an example showing exact this scenario:

>>> lst = [6, 7, [1, 2], "hello"]
>>> lst_2 = lst.copy()
>>> lst_2[2].append(42)
>>> lst[2]
[1, 2, 42]

Changing the third list element of the copied list impacts the third list element of the original list.

Python List Copy Deep

Having understood the concept of a shallow copy, it’s now easy to understand the concept of a deep copy. A shallow copy only copies the references of the list elements. A deep copy copies the list elements themselves which can lead to a highly recursive behavior because the list elements may be lists themselves that need to be copied deeply and so on.

Here’s a simple deep copy of the same list as shown previously:

In contrast to the shallow copy, the list [1, 2] is copied separately for the deep copy list. If one changes this nested list in the original list, the change would not be visible at the deep copy. (Because the nested list of the deep copy list is an independent object in memory.)

Note that in a deep copy, the string object must not be copied. Why? Because strings are immutable so you cannot change them (and, thus, there will be no dirty “side effects” seen by other copies of the list pointing to the same object in memory.

To get a deep copy in Python, use the copy module and use the deepcopy() method:

>>> import copy
>>> lst = [6, 7, [1, 2], "hello"]
>>> lst_2 = copy.deepcopy(lst)
>>> lst_2[2].append(42)
>>> lst[2]
[1, 2]

How to Copy a Python List (Alternatives)?

Say, you want to copy the list. What options are there?

Method Description
list.copy() Returns a shallow copy of the list.
import copy
copy.deepcopy(list)
Import the copy module and uses its method to create a deep copy of list.
list[:] Use slicing with default indices to create a shallow copy of the list.
list(x) use the built-in list constructor list(...) to create a shallow copy of the list x.
[el for el in lst] Use list comprehension to create a shallow copy of the original list lst.

Slicing belongs to the fastest methods (very dirty benchmark here). If you need to refresh your Python slicing skills, here’s a tutorial on the Finxter blog:

Related Articles:

Python List Copy Not Working

The main reason why the list.copy() method may not work for you is because you assume that it creates a deep copy when, in reality, it only creates a shallow copy of the list. To create a deep copy where the list elements themselves are copied (e.g. for multi-dimensional lists), simply import the copy module and use its method deepcopy(x) to copy list x.

>>> import copy
>>> lst = [[1, 2], 3, 4]
>>> lst_2 = copy.deepcopy(lst)

Python List Copy And Append

How to copy a list and append an element in one line of Python code?

Simply use slicing to copy the list and the list concatenation operator + to add the list of a single element [x] to the result. But there are other nice ways, too. Check out the following ways to append element x to a given list lst and return the result as a copy:

  • lst[:] + [x]
  • lst.copy() + [x]
  • [*lst, x]

The third way to copy a list and append a new element is my personal favorite because it’s fast, easy-to-read, and concise. It uses the asterisk operator to unpack the elements of the original list into a new list.

Python List Copy By Value

Do you want to copy all elements in your list “by value”? In other words, you want not only the list object to be copied (shallow copy) but also the list elements (deep copy).

This can be done with the deepcopy() method of Python’s copy library. Here’s an example:

>>> import copy
>>> lst = [6, 7, [1, 2], "hello"]
>>> lst_2 = copy.deepcopy(lst)
>>> lst_2[2].append(42)
>>> lst[2]
[1, 2]

The element 42 was not appended to the nested list of lst.

Python List Copy With Slice

You can simply copy a list lst by using the slice operation lst[:] with default start and stop indices so that all elements are copied in the list. This creates a shallow copy of the list lst.

Related Articles:

Python List Copy Without First Element

To copy a list without its first element, simply use slicing list[1:]. By setting the start index to 1 all elements with index larger or equal to 1 are copied into the new list.

Here’s an example:

>>> lst = [1, 2, 3, 4]
>>> lst[1:]
[2, 3, 4]

Python List Copy Without Last Element

To copy a list without its last element, simply use slicing list[:-1]. By setting the start index to -1 (the right-most list element) all elements but the last one are copied into the new list.

Here’s an example:

>>> lst = [1, 2, 3, 4]
>>> lst[:-1]
[1, 2, 3]

Python List Copy Time Complexity

The time complexity of shallow list copying—examples are list.copy() or slicing list[:]—is linear to the number of elements in the list. For n list elements, the time complexity is O(n). Why? Because Python goes over all elements in the list and adds a copy of the object reference to the new list (copy by reference).

I wrote a quick script to evaluate that the time complexity of copying a list is, in fact, linear in the number of list elements:

import matplotlib.pyplot as plt
import time y = []
for i in [100000 * j for j in range(10)]: lst = list(range(i)) t0 = time.time() lst_2 = lst[:] t1 = time.time() y.append(t1-t0) plt.plot(y)
plt.xlabel("List elements (10**5)")
plt.ylabel("Time (sec)")
plt.show()

Here’s the result:

The runtime grows linearly in the number of list elements.

Python List Copy Partially

How to copy a list partially? To copy only the elements between start index (included) and stop index (excluded), use slicing like this: list[start:stop]. This results in a new list that contains only parts of the list.

Python List Copy Multi-Dimensional List

To copy a multi-dimensional list (a list of lists), you need to create a deep copy. You can accomplish this with the copy library’s deepcopy() method as follows:

>>> import copy
>>> lst = [[1, 2, 3], [4, 5, 6]]
>>> lst_2 = copy.deepcopy(lst)
>>> lst_2
[[1, 2, 3], [4, 5, 6]]

Now check if the copy is really deep by clearing the first list element in the copy:

>>> lst_2[0].clear()
>>> lst
[[1, 2, 3], [4, 5, 6]]
>>> lst_2
[[], [4, 5, 6]]

You can see that the copy was really deep because the first element of the lst was not affected by the clear() method that removed all elements for the deep copy lst_2.

Python List copy() Thread Safe

Do you have a multiple threads that access your list at the same time? Then you need to be sure that the list operations (such as copy()) are actually thread safe.

In other words: can you call the copy() operation in two threads on the same list at the same time? (And can you be sure that the result is meaningful?)

The answer is yes (if you use the cPython implementation). The reason is Python’s global interpreter lock that ensures that a thread that’s currently working on it’s code will first finish its current basic Python operation as defined by the cPython implementation. Only if it terminates with this operation will the next thread be able to access the computational resource. This is ensured with a sophisticated locking scheme by the cPython implementation.

The only thing you need to know is that each basic operation in the cPython implementation is atomic. It’s executed wholly and at once before any other thread has the chance to run on the same virtual engine. Therefore, there are no race conditions. An example for such a race condition would be the following: the first thread reads a value from the list, the second threads overwrites the value, and the first thread overwrites the value again invalidating the second thread’s operation.

All cPython operations are thread-safe. But if you combine those operations into higher-level functions, those are not generally thread safe as they consist of many (possibly interleaving) operations.

Where to Go From Here?

The list.copy() method creates a shallow copy of the list. The copy.deepcopy(list) method creates a deep copy of the list.

You’ve learned the ins and outs of this important Python list method.

If you keep struggling with those basic Python commands and you feel stuck in your learning progress, I’ve got something for you: Python One-Liners (Amazon Link).

In the book, I’ll give you a thorough overview of critical computer science topics such as machine learning, regular expression, data science, NumPy, and Python basics—all in a single line of Python code!

Get the book from Amazon!

OFFICIAL BOOK DESCRIPTION: Python One-Liners will show readers how to perform useful tasks with one line of Python code. Following a brief Python refresher, the book covers essential advanced topics like slicing, list comprehension, broadcasting, lambda functions, algorithms, regular expressions, neural networks, logistic regression and more. Each of the 50 book sections introduces a problem to solve, walks the reader through the skills necessary to solve that problem, then provides a concise one-liner Python solution with a detailed explanation.

Posted on Leave a comment

Python List clear()

Surprisingly, even advanced Python coders don’t know about the clear() method of Python lists. Time to change that!

Definition and Usage: The list.clear() method removes all elements from an existing list. The list becomes empty again.

Here’s a short example:

>>> lst = [1, 2, 3, 4, 5]
>>> lst.clear()
>>> lst
[]

In the first line, you create the list lst consisting of five integers. You then remove all elements from the list. The result is the empty list.

Puzzle – Try It Yourself:

Syntax: You can call this method on each list object in Python. Here’s the syntax:

list.clear()

Arguments: The method doesn’t take any argument.

Return value: The method list.clear() has return value None. It operates on an existing list and, therefore, doesn’t return a new list with the removed element

Video:

Python List clear() vs New List

Now, if you’re an alert reader, you may ask the following interesting question: why to use the clear() method in the first place when you also can simply create a new list and be done with it?

Here’s an example where both ways lead to the same result:

>>> lst = [1, 2, 3]
>>> lst.clear()
>>> lst
[]
>>> lst = [1, 2, 3]
>>> lst = []
>>> lst
[]

I know the code seems to be a bit odd but it shows that instead of clearing an existing list, you can also create a new list. In this case, this leads to the exact same result.

However, Python is an object-oriented language. And if you just create a new object and assign it to a variable, the original list still exists in memory. And other variables may point to the object.

Consider the following code snippet that exemplifies this:

lst = [1, 2, 3]
lst_2 = lst
lst = []
print(lst_2)
# [1, 2, 3]

I’ve created a Python visualization for you so that you can see the objects in memory:

Simply assigning a new list to the variable lst will leave the other variable lst_2 unaffected. Instead, you should have used lst.clear() to make sure that both variables now point to the same empty list object.

lst = [1, 2, 3]
lst_2 = lst
lst.clear()
print(lst_2)
# []

Python List clear() Memory

The effect of the clear() method is that the list is now empty.

In theory, you released the Python virtual machine from the burden of keeping the elements in the memory. Python uses reference counting to determine if some elements in the memory are not referenced anymore (and, thus, can be considered unused). Those elements will be removed—we say, they are deallocated from memory. If you clear the list, you essentially remove all references from the list to the list elements. However, some old list elements may still be referenced from the outside (e.g. by another variable). So they are not necessarily removed because they may still be needed! Just keep this in mind when clearing the list.

In practice, however, even referenced elements may still exist in the memory until the Python garbage collector (or even the operating system) removes the elements from memory.

Python List clear() Complexity

The runtime complexity of list.clear() is O(n) for a list with n elements. Why? Well, you first need to understand what happens if you remove all elements from a list. The list elements are not physically (or, for that matter, digitally) stored in the list. The list contains only references to the real list element objects in memory. If you clear the list, you remove all those references.

The garbage collector in Python goes over all elements in the memory to remove the ones that have a reference count of zero. Why? Because they are the ones that cannot be accessed in the code. Thus, the garbage collector can safely assume that they are unused and are not needed anymore. As you see, the garbage collector needs the reference count information for each element in memory.

The algorithm when clearing a list is simple: reduce the reference count of each list element object by one. The objects that end up with reference count zero can now be removed from memory. But as you need to go over all list elements, the runtime complexity is linear to the list size.

Python List clear() Not Working

The Python list.clear() method was added in Python 3.3 (official source). So if you try to use it for any Python version before that, you must use the del list[:] method that is semantically equivalent and works for earlier Python versions, too.

Related articles on the Finxter blog:

Python List clear() Version 2.7

Have you tried to use Python list.clear() in Python 2.7? It’s not possible. The clear() method was added in Python 3.3 (official source). So if you try to use it for any Python version before that (including 2.7), you must use the del list[:] method that is semantically equivalent and works for earlier Python versions, too.

Related articles on the Finxter blog:

Python List clear() vs del

You may ask: what’s the difference between the list.clear() method and the del operation?

The answer is simple: there isn’t any semantic difference. The list.clear() method is just syntactical sugar for del list[:] (source).

Here’s an example demonstrating that both are, in fact, the same:

>>> lst = [1, 2, 3]
>>> lst.clear()
>>> lst
[]
>>> lst = [1, 2, 3]
>>> del lst[:]
>>> lst
[]

List Removal Alternatives

There are some alternative list methods to remove elements from the list. See the overview table:

Method Description
lst.remove(x) Remove an element from the list (by value)
lst.pop() Remove an element from the list (by index) and return the element
lst.clear() Remove all elements from the list
del lst[3] Remove one or more elements from the list (by index or slice)
List comprehension Remove all elements that meet a certain condition

Python List clear() Thread Safe

Do you have a multiple threads that access your list at the same time? Then you need to be sure that the list operations (such as clear()) are actually thread safe.

In other words: can you call the clear() operation in two threads on the same list at the same time? (And can you be sure that the result is meaningful?)

The answer is yes (if you use the cPython implementation). The reason is Python’s global interpreter lock that ensures that a thread that’s currently working on it’s code will first finish its current basic Python operation as defined by the cPython implementation. Only if it terminates with this operation will the next thread be able to access the computational resource. This is ensured with a sophisticated locking scheme by the cPython implementation.

The only thing you need to know is that each basic operation in the cPython implementation is atomic. It’s executed wholly and at once before any other thread has the chance to run on the same virtual engine. Therefore, there are no race conditions. An example for such a race condition would be the following: the first thread reads a value from the list, the second threads overwrites the value, and the first thread overwrites the value again invalidating the second thread’s operation.

All cPython operations are thread-safe. But if you combine those operations into higher-level functions, those are not generally thread safe as they consist of many (possibly interleaving) operations.

Python List Clear Duplicates

How to remove all duplicates of a given value in the list?

The naive approach is to go over each element and check whether this element already exists in the list. If so, remove it. However, this takes a few lines of code.

A shorter and more concise way is to create a dictionary out of the elements in the list. Each list element becomes a new key to the dictionary. All elements that occur multiple times will be assigned to the same key. The dictionary contains only unique keys—there cannot be multiple equal keys.

As dictionary values, you simply take dummy values (per default).

Related blog articles:

Then, you simply convert the dictionary back to a list throwing away the dummy values. As the dictionary keys stay in the same order, you don’t lose the order information of the original list elements.

Here’s the code:

>>> lst = [1, 1, 1, 3, 2, 5, 5, 2]
>>> dic = dict.fromkeys(lst)
>>> dic
{1: None, 3: None, 2: None, 5: None}
>>> duplicate_free = list(dic)
>>> duplicate_free
[1, 3, 2, 5]

Where to Go From Here?

The list.clear() method removes all elements from the list.

You’ve learned the ins and outs of this important Python list method.

If you keep struggling with those basic Python commands and you feel stuck in your learning progress, I’ve got something for you: Python One-Liners (Amazon Link).

In the book, I’ll give you a thorough overview of critical computer science topics such as machine learning, regular expression, data science, NumPy, and Python basics—all in a single line of Python code!

Get the book from Amazon!

OFFICIAL BOOK DESCRIPTION: Python One-Liners will show readers how to perform useful tasks with one line of Python code. Following a brief Python refresher, the book covers essential advanced topics like slicing, list comprehension, broadcasting, lambda functions, algorithms, regular expressions, neural networks, logistic regression and more. Each of the 50 book sections introduces a problem to solve, walks the reader through the skills necessary to solve that problem, then provides a concise one-liner Python solution with a detailed explanation.

Posted on Leave a comment

Python List remove()

This tutorial shows you everything you need to know to help you master the essential remove() method of the most fundamental container data type in the Python programming language.

Definition and Usage:

The list.remove(element) method removes the first occurrence of the element from an existing list. It does not, however, remove all occurrences of the element in the list!

Here’s a short example:

>>> lst = [1, 2, 99, 4, 99]
>>> lst.remove(99)
>>> lst
[1, 2, 4, 99]

In the first line of the example, you create the list lst. You then remove the integer element 99 from the list—but only its first occurrence. The result is the list with only four elements [1, 2, 4, 99].

Try it yourself:

Syntax:

You can call this method on each list object in Python. Here’s the syntax:

list.remove(element)

Arguments:

Argument Description
element Object you want to remove from the list. Only the first occurrence of the element is removed.

Return value:

The method list.remove(element) has return value None. It operates on an existing list and, therefore, doesn’t return a new list with the removed element

Video:

Code Puzzle:

Now you know the basics. Let’s deepen your understanding with a short code puzzle—can you solve it?

# Puzzle
presidents = ['Obama', 'Trump', 'Washington']
p2 = presidents[:2]
p2.remove('Trump')
print(presidents)
# What's the output of this code snippet?

You can check out the solution on the Finxter app.

Overview:

There are some alternative ways to remove elements from the list. See the overview table:

Method Description
lst.remove(x) Remove an element from the list (by value)
lst.pop() Remove an element from the list (by index) and return the element
lst.clear() Remove all elements from the list
del lst[3] Remove one or more elements from the list (by index or slice)
List comprehension Remove all elements that meet a certain condition

Next, you’ll dive into each of those methods to gain some deep understanding.

remove() — Remove An Element by Value

To remove an element from the list, use the list.remove(element) method you’ve already seen previously:

>>> lst = ["Alice", 3, "alice", "Ann", 42]
>>> lst.remove("Ann")
>>> lst
['Alice', 3, 'alice', 42]

Try it yourself:

The method goes from left to right and removes the first occurrence of the element that’s equal to the one to be removed.

Removed Element Does Not Exist

If you’re trying to remove element x from the list but x does not exist in the list, Python throws a Value error:

>>> lst = ['Alice', 'Bob', 'Ann']
>>> lst.remove('Frank')
Traceback (most recent call last): File "<pyshell#19>", line 1, in <module> lst.remove('Frank')
ValueError: list.remove(x): x not in list

pop() — Remove An Element by Index

Per default, the pop() method removes the last element from the list and returns the element.

>>> lst = ['Alice', 'Bob', 'Ann']
>>> lst.pop() 'Ann'
>>> lst
['Alice', 'Bob']

But you can also define the optional index argument. In this case, you’ll remove the element at the given index—a little known Python secret!

>>> lst = ['Alice', 'Bob', 'Ann']
>>> lst.pop(1) 'Bob'
>>> lst
['Alice', 'Ann']

clear() — Remove All Elements

The clear() method simply removes all elements from a given list object.

>>> lst = ['Alice', 'Bob', 'Ann']
>>> lst.clear()
>>> lst
[]

del — Remove Elements by Index or Slice

This trick is also relatively unknown among Python beginners:

  • Use del lst[index] to remove the element at index.
  • Use del lst[start:stop] to remove all elements in the slice.
>>> lst = list(range(10))
>>> lst
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> del lst[5]
>>> lst
[0, 1, 2, 3, 4, 6, 7, 8, 9]
>>> del lst[:4]
>>> lst
[4, 6, 7, 8, 9]

Related blog articles:

List Comprehension — Remove Elements Conditionally

Okay, this is kind of cheating because this method does not really remove elements from a list object. It merely creates a new list with some elements that meet your condition.

List comprehension is a compact way of creating lists. The simple formula is [ expression + context ].

  • Expression: What to do with each list element?
  • Context: What list elements to select? It consists of an arbitrary number of for and if statements.

The example [x for x in range(3)] creates the list [0, 1, 2].

You can also define a condition such as all odd values x%2==1 in the context part by using an if condition. This leads us to a way to remove all elements that do not meet a certain condition in a given list.

>>> lst = list(range(10))
>>> lst_new = [x for x in lst if x%2]
>>> lst_new
[1, 3, 5, 7, 9] 

While you iterate over the whole list lst, the condition x%2 requires that the elements are odd.

Related blog articles:

Python List remove() All

The list.remove(x) method only removes the first occurrence of element x from the list.

But what if you want to remove all occurrences of element x from a given list?

The answer is to use a simple loop:

lst = ['Ann', 'Ann', 'Ann', 'Alice', 'Ann', 'Bob']
x = 'Ann' while x in lst: lst.remove(x) print(lst)
# ['Alice', 'Bob']

You simply call the remove() method again and again until element x is not in the list anymore.

Python List Remove Duplicates

How to remove all duplicates of a given value in the list?

The naive approach is to go over each element and check whether this element already exists in the list. If so, remove it. However, this takes a few lines of code.

A shorter and more concise way is to create a dictionary out of the elements in the list. Each list element becomes a new key to the dictionary. All elements that occur multiple times will be assigned to the same key. The dictionary contains only unique keys—there cannot be multiple equal keys.

As dictionary values, you simply take dummy values (per default).

Related blog articles:

Then, you simply convert the dictionary back to a list throwing away the dummy values. As the dictionary keys stay in the same order, you don’t lose the order information of the original list elements.

Here’s the code:

>>> lst = [1, 1, 1, 3, 2, 5, 5, 2]
>>> dic = dict.fromkeys(lst)
>>> dic
{1: None, 3: None, 2: None, 5: None}
>>> duplicate_free = list(dic)
>>> duplicate_free
[1, 3, 2, 5]

Python List remove() If Exists

How to remove an element from a list—but only if it exists?

The problem is that if you try to remove an element from the list that doesn’t exist, Python throws a Value Error. You can avoid this by checking the membership of the element to be removed first:

>>> lst = ['Alice', 'Bob', 'Ann']
>>> lst.remove('Frank') if 'Frank' in lst else None
>>> lst
['Alice', 'Bob', 'Ann']

This makes use of the Python one-liner feature of conditional assignment (also called the ternary operator).

Related blog articles:

Python List remove() Thread Safe

Do you have a multiple threads that access your list at the same time? Then you need to be sure that the list operations (such as remove()) are actually thread safe.

In other words: can you call the remove() operation in two threads on the same list at the same time? (And can you be sure that the result is meaningful?)

The answer is yes (if you use the cPython implementation). The reason is Python’s global interpreter lock that ensures that a thread that’s currently working on it’s code will first finish its current basic Python operation as defined by the cPython implementation. Only if it terminates with this operation will the next thread be able to access the computational resource. This is ensured with a sophisticated locking scheme by the cPython implementation.

The only thing you need to know is that each basic operation in the cPython implementation is atomic. It’s executed wholly and at once before any other thread has the chance to run on the same virtual engine. Therefore, there are no race conditions. An example for such a race condition would be the following: the first thread reads a value from the list, the second threads overwrites the value, and the first thread overwrites the value again invalidating the second thread’s operation.

All cPython operations are thread-safe. But if you combine those operations into higher-level functions, those are not generally thread safe as they consist of many (possibly interleaving) operations.

Where to Go From Here?

The list.remove(element) method removes the first occurrence of element from the list.

You’ve learned the ins and outs of this important Python list method.

If you keep struggling with those basic Python commands and you feel stuck in your learning progress, I’ve got something for you: Python One-Liners (Amazon Link).

In the book, I’ll give you a thorough overview of critical computer science topics such as machine learning, regular expression, data science, NumPy, and Python basics—all in a single line of Python code!

Get the book from Amazon!

OFFICIAL BOOK DESCRIPTION: Python One-Liners will show readers how to perform useful tasks with one line of Python code. Following a brief Python refresher, the book covers essential advanced topics like slicing, list comprehension, broadcasting, lambda functions, algorithms, regular expressions, neural networks, logistic regression and more. Each of the 50 book sections introduces a problem to solve, walks the reader through the skills necessary to solve that problem, then provides a concise one-liner Python solution with a detailed explanation.