• Python »
  • 3.12.3 Documentation »
  • The Python Tutorial »
  • 5. Data Structures
  • Theme Auto Light Dark |

5. Data Structures ¶

This chapter describes some things you’ve learned about already in more detail, and adds some new things as well.

5.1. More on Lists ¶

The list data type has some more methods. Here are all of the methods of list objects:

Add an item to the end of the list. Equivalent to a[len(a):] = [x] .

Extend the list by appending all the items from the iterable. Equivalent to a[len(a):] = iterable .

Insert an item at a given position. The first argument is the index of the element before which to insert, so a.insert(0, x) inserts at the front of the list, and a.insert(len(a), x) is equivalent to a.append(x) .

Remove the first item from the list whose value is equal to x . It raises a ValueError if there is no such item.

Remove the item at the given position in the list, and return it. If no index is specified, a.pop() removes and returns the last item in the list. It raises an IndexError if the list is empty or the index is outside the list range.

Remove all items from the list. Equivalent to del a[:] .

Return zero-based index in the list of the first item whose value is equal to x . Raises a ValueError if there is no such item.

The optional arguments start and end are interpreted as in the slice notation and are used to limit the search to a particular subsequence of the list. The returned index is computed relative to the beginning of the full sequence rather than the start argument.

Return the number of times x appears in the list.

Sort the items of the list in place (the arguments can be used for sort customization, see sorted() for their explanation).

Reverse the elements of the list in place.

Return a shallow copy of the list. Equivalent to a[:] .

An example that uses most of the list methods:

You might have noticed that methods like insert , remove or sort that only modify the list have no return value printed – they return the default None . [ 1 ] This is a design principle for all mutable data structures in Python.

Another thing you might notice is that not all data can be sorted or compared. For instance, [None, 'hello', 10] doesn’t sort because integers can’t be compared to strings and None can’t be compared to other types. Also, there are some types that don’t have a defined ordering relation. For example, 3+4j < 5+7j isn’t a valid comparison.

5.1.1. Using Lists as Stacks ¶

The list methods make it very easy to use a list as a stack, where the last element added is the first element retrieved (“last-in, first-out”). To add an item to the top of the stack, use append() . To retrieve an item from the top of the stack, use pop() without an explicit index. For example:

5.1.2. Using Lists as Queues ¶

It is also possible to use a list as a queue, where the first element added is the first element retrieved (“first-in, first-out”); however, lists are not efficient for this purpose. While appends and pops from the end of list are fast, doing inserts or pops from the beginning of a list is slow (because all of the other elements have to be shifted by one).

To implement a queue, use collections.deque which was designed to have fast appends and pops from both ends. For example:

5.1.3. List Comprehensions ¶

List comprehensions provide a concise way to create lists. Common applications are to make new lists where each element is the result of some operations applied to each member of another sequence or iterable, or to create a subsequence of those elements that satisfy a certain condition.

For example, assume we want to create a list of squares, like:

Note that this creates (or overwrites) a variable named x that still exists after the loop completes. We can calculate the list of squares without any side effects using:

or, equivalently:

which is more concise and readable.

A list comprehension consists of brackets containing an expression followed by a for clause, then zero or more for or if clauses. The result will be a new list resulting from evaluating the expression in the context of the for and if clauses which follow it. For example, this listcomp combines the elements of two lists if they are not equal:

and it’s equivalent to:

Note how the order of the for and if statements is the same in both these snippets.

If the expression is a tuple (e.g. the (x, y) in the previous example), it must be parenthesized.

List comprehensions can contain complex expressions and nested functions:

5.1.4. Nested List Comprehensions ¶

The initial expression in a list comprehension can be any arbitrary expression, including another list comprehension.

Consider the following example of a 3x4 matrix implemented as a list of 3 lists of length 4:

The following list comprehension will transpose rows and columns:

As we saw in the previous section, the inner list comprehension is evaluated in the context of the for that follows it, so this example is equivalent to:

which, in turn, is the same as:

In the real world, you should prefer built-in functions to complex flow statements. The zip() function would do a great job for this use case:

See Unpacking Argument Lists for details on the asterisk in this line.

5.2. The del statement ¶

There is a way to remove an item from a list given its index instead of its value: the del statement. This differs from the pop() method which returns a value. The del statement can also be used to remove slices from a list or clear the entire list (which we did earlier by assignment of an empty list to the slice). For example:

del can also be used to delete entire variables:

Referencing the name a hereafter is an error (at least until another value is assigned to it). We’ll find other uses for del later.

5.3. Tuples and Sequences ¶

We saw that lists and strings have many common properties, such as indexing and slicing operations. They are two examples of sequence data types (see Sequence Types — list, tuple, range ). Since Python is an evolving language, other sequence data types may be added. There is also another standard sequence data type: the tuple .

A tuple consists of a number of values separated by commas, for instance:

As you see, on output tuples are always enclosed in parentheses, so that nested tuples are interpreted correctly; they may be input with or without surrounding parentheses, although often parentheses are necessary anyway (if the tuple is part of a larger expression). It is not possible to assign to the individual items of a tuple, however it is possible to create tuples which contain mutable objects, such as lists.

Though tuples may seem similar to lists, they are often used in different situations and for different purposes. Tuples are immutable , and usually contain a heterogeneous sequence of elements that are accessed via unpacking (see later in this section) or indexing (or even by attribute in the case of namedtuples ). Lists are mutable , and their elements are usually homogeneous and are accessed by iterating over the list.

A special problem is the construction of tuples containing 0 or 1 items: the syntax has some extra quirks to accommodate these. Empty tuples are constructed by an empty pair of parentheses; a tuple with one item is constructed by following a value with a comma (it is not sufficient to enclose a single value in parentheses). Ugly, but effective. For example:

The statement t = 12345, 54321, 'hello!' is an example of tuple packing : the values 12345 , 54321 and 'hello!' are packed together in a tuple. The reverse operation is also possible:

This is called, appropriately enough, sequence unpacking and works for any sequence on the right-hand side. Sequence unpacking requires that there are as many variables on the left side of the equals sign as there are elements in the sequence. Note that multiple assignment is really just a combination of tuple packing and sequence unpacking.

5.4. Sets ¶

Python also includes a data type for sets . A set is an unordered collection with no duplicate elements. Basic uses include membership testing and eliminating duplicate entries. Set objects also support mathematical operations like union, intersection, difference, and symmetric difference.

Curly braces or the set() function can be used to create sets. Note: to create an empty set you have to use set() , not {} ; the latter creates an empty dictionary, a data structure that we discuss in the next section.

Here is a brief demonstration:

Similarly to list comprehensions , set comprehensions are also supported:

5.5. Dictionaries ¶

Another useful data type built into Python is the dictionary (see Mapping Types — dict ). Dictionaries are sometimes found in other languages as “associative memories” or “associative arrays”. Unlike sequences, which are indexed by a range of numbers, dictionaries are indexed by keys , which can be any immutable type; strings and numbers can always be keys. Tuples can be used as keys if they contain only strings, numbers, or tuples; if a tuple contains any mutable object either directly or indirectly, it cannot be used as a key. You can’t use lists as keys, since lists can be modified in place using index assignments, slice assignments, or methods like append() and extend() .

It is best to think of a dictionary as a set of key: value pairs, with the requirement that the keys are unique (within one dictionary). A pair of braces creates an empty dictionary: {} . Placing a comma-separated list of key:value pairs within the braces adds initial key:value pairs to the dictionary; this is also the way dictionaries are written on output.

The main operations on a dictionary are storing a value with some key and extracting the value given the key. It is also possible to delete a key:value pair with del . If you store using a key that is already in use, the old value associated with that key is forgotten. It is an error to extract a value using a non-existent key.

Performing list(d) on a dictionary returns a list of all the keys used in the dictionary, in insertion order (if you want it sorted, just use sorted(d) instead). To check whether a single key is in the dictionary, use the in keyword.

Here is a small example using a dictionary:

The dict() constructor builds dictionaries directly from sequences of key-value pairs:

In addition, dict comprehensions can be used to create dictionaries from arbitrary key and value expressions:

When the keys are simple strings, it is sometimes easier to specify pairs using keyword arguments:

5.6. Looping Techniques ¶

When looping through dictionaries, the key and corresponding value can be retrieved at the same time using the items() method.

When looping through a sequence, the position index and corresponding value can be retrieved at the same time using the enumerate() function.

To loop over two or more sequences at the same time, the entries can be paired with the zip() function.

To loop over a sequence in reverse, first specify the sequence in a forward direction and then call the reversed() function.

To loop over a sequence in sorted order, use the sorted() function which returns a new sorted list while leaving the source unaltered.

Using set() on a sequence eliminates duplicate elements. The use of sorted() in combination with set() over a sequence is an idiomatic way to loop over unique elements of the sequence in sorted order.

It is sometimes tempting to change a list while you are looping over it; however, it is often simpler and safer to create a new list instead.

5.7. More on Conditions ¶

The conditions used in while and if statements can contain any operators, not just comparisons.

The comparison operators in and not in are membership tests that determine whether a value is in (or not in) a container. The operators is and is not compare whether two objects are really the same object. All comparison operators have the same priority, which is lower than that of all numerical operators.

Comparisons can be chained. For example, a < b == c tests whether a is less than b and moreover b equals c .

Comparisons may be combined using the Boolean operators and and or , and the outcome of a comparison (or of any other Boolean expression) may be negated with not . These have lower priorities than comparison operators; between them, not has the highest priority and or the lowest, so that A and not B or C is equivalent to (A and (not B)) or C . As always, parentheses can be used to express the desired composition.

The Boolean operators and and or are so-called short-circuit operators: their arguments are evaluated from left to right, and evaluation stops as soon as the outcome is determined. For example, if A and C are true but B is false, A and B and C does not evaluate the expression C . When used as a general value and not as a Boolean, the return value of a short-circuit operator is the last evaluated argument.

It is possible to assign the result of a comparison or other Boolean expression to a variable. For example,

Note that in Python, unlike C, assignment inside expressions must be done explicitly with the walrus operator := . This avoids a common class of problems encountered in C programs: typing = in an expression when == was intended.

5.8. Comparing Sequences and Other Types ¶

Sequence objects typically may be compared to other objects with the same sequence type. The comparison uses lexicographical ordering: first the first two items are compared, and if they differ this determines the outcome of the comparison; if they are equal, the next two items are compared, and so on, until either sequence is exhausted. If two items to be compared are themselves sequences of the same type, the lexicographical comparison is carried out recursively. If all items of two sequences compare equal, the sequences are considered equal. If one sequence is an initial sub-sequence of the other, the shorter sequence is the smaller (lesser) one. Lexicographical ordering for strings uses the Unicode code point number to order individual characters. Some examples of comparisons between sequences of the same type:

Note that comparing objects of different types with < or > is legal provided that the objects have appropriate comparison methods. For example, mixed numeric types are compared according to their numeric value, so 0 equals 0.0, etc. Otherwise, rather than providing an arbitrary ordering, the interpreter will raise a TypeError exception.

Table of Contents

  • 5.1.1. Using Lists as Stacks
  • 5.1.2. Using Lists as Queues
  • 5.1.3. List Comprehensions
  • 5.1.4. Nested List Comprehensions
  • 5.2. The del statement
  • 5.3. Tuples and Sequences
  • 5.5. Dictionaries
  • 5.6. Looping Techniques
  • 5.7. More on Conditions
  • 5.8. Comparing Sequences and Other Types

Previous topic

4. More Control Flow Tools

  • Report a Bug
  • Show Source

Learn Python practically and Get Certified .

Popular Tutorials

Popular examples, reference materials, learn python interactively, python introduction.

  • Get Started With Python
  • Your First Python Program
  • Python Comments

Python Fundamentals

  • Python Variables and Literals
  • Python Type Conversion
  • Python Basic Input and Output
  • Python Operators

Python Flow Control

  • Python if...else Statement
  • Python for Loop
  • Python while Loop
  • Python break and continue
  • Python pass Statement

Python Data types

  • Python Numbers and Mathematics
  • Python List
  • Python Tuple
  • Python String
  • Python Sets

Python Dictionary

  • Python Functions
  • Python Function Arguments
  • Python Variable Scope
  • Python Global Keyword
  • Python Recursion
  • Python Modules
  • Python Package
  • Python Main function

Python Files

  • Python Directory and Files Management
  • Python CSV: Read and Write CSV files
  • Reading CSV files in Python
  • Writing CSV files in Python
  • Python Exception Handling
  • Python Exceptions
  • Python Custom Exceptions

Python Object & Class

  • Python Objects and Classes
  • Python Inheritance
  • Python Multiple Inheritance
  • Polymorphism in Python
  • Python Operator Overloading

Python Advanced Topics

  • List comprehension
  • Python Lambda/Anonymous Function
  • Python Iterators
  • Python Generators
  • Python Namespace and Scope
  • Python Closures
  • Python Decorators
  • Python @property decorator
  • Python RegEx

Python Date and Time

  • Python datetime
  • Python strftime()
  • Python strptime()
  • How to get current date and time in Python?
  • Python Get Current Time
  • Python timestamp to datetime and vice-versa
  • Python time Module
  • Python sleep()

Additional Topic

  • Precedence and Associativity of Operators in Python
  • Python Keywords and Identifiers
  • Python Asserts
  • Python Json
  • Python *args and **kwargs

Python Tutorials

Python reversed()

Python Dictionary clear()

  • Python Dictionary items()
  • Python Dictionary keys()

Python Dictionary fromkeys()

  • Python Nested Dictionary

A Python dictionary is a collection of items, similar to lists and tuples. However, unlike lists and tuples, each item in a dictionary is a key-value pair (consisting of a key and a value).

  • Create a Dictionary

We create a dictionary by placing key: value pairs inside curly brackets {} , separated by commas. For example,

Key Value Pairs in a Dictionary

  • Dictionary keys must be immutable, such as tuples, strings, integers, etc. We cannot use mutable (changeable) objects such as lists as keys.
  • We can also create a dictionary using a Python built-in function dict() . To learn more, visit Python dict() .

Valid and Invalid Dictionaries

Immutable objects can't be changed once created. Some immutable objects in Python are integer, tuple and string.

In this example, we have used integers, tuples, and strings as keys for the dictionaries. When we used a list as a key, an error message occurred due to the list's mutable nature.

Note: Dictionary values can be of any data type, including mutable types like lists.

The keys of a dictionary must be unique. If there are duplicate keys, the later value of the key overwrites the previous value.

Here, the key Harry Potter is first assigned to Gryffindor . However, there is a second entry where Harry Potter is assigned to Slytherin .

As duplicate keys are not allowed in a dictionary, the last entry Slytherin overwrites the previous value Gryffindor .

  • Access Dictionary Items

We can access the value of a dictionary item by placing the key inside square brackets.

Note: We can also use the get() method to access dictionary items.

  • Add Items to a Dictionary

We can add an item to a dictionary by assigning a value to a new key. For example,

  • Remove Dictionary Items

We can use the del statement to remove an element from a dictionary. For example,

Note : We can also use the pop() method to remove an item from a dictionary.

If we need to remove all items from a dictionary at once, we can use the clear() method.

  • Change Dictionary Items

Python dictionaries are mutable (changeable). We can change the value of a dictionary element by referring to its key. For example,

Note : We can also use the update() method to add or change dictionary items.

  • Iterate Through a Dictionary

A dictionary is an ordered collection of items (starting from Python 3.7), therefore it maintains the order of its items.

We can iterate through dictionary keys one by one using a for loop .

  • Find Dictionary Length

We can find the length of a dictionary by using the len() function.

  • Python Dictionary Methods

Here are some of the commonly used dictionary methods .

  • Dictionary Membership Test

We can check whether a key exists in a dictionary by using the in and not in operators.

Note: The in operator checks whether a key exists; it doesn't check whether a value exists or not.

Table of Contents

Write a function to merge two dictionaries.

  • Merge dict1 and dict2 , then return the merged dictionary.

Video: Python Dictionaries to Store key/value Pairs

Sorry about that.

Related Tutorials

Python Library

Python Tutorial

Python Data Types

5 Best Ways to Initialize a List of Dictionaries in Python

💡 Problem Formulation: When working with data in Python, it’s common to organize complex information using lists of dictionaries. This approach enables efficient storage of related data with key-value associations within each dictionary in the list. For instance, if you want to store user data such as usernames and email addresses, you would need to initialize a list of dictionaries where each dictionary represents a user: [{"username": "example", "email": "[email protected]"}, ...] . The goal is to find the most efficient and readable ways to initialize this data structure.

Method 1: Using a For Loop

Creating a list of dictionaries through a for loop is a straightforward and intuitive way to initialize this data structure. It’s especially handy when the dictionaries are populated based on another sequence or range of values.

Here’s an example:

The above snippet uses a for loop to append each dictionary to the list users . We’re using a range of numbers to create unique values for the ‘id’, ‘username’, and ’email’ keys. This method is very clear and easy to modify, perfect for beginners or for cases where the dictionaries might vary greatly in content.

Method 2: List Comprehensions

List comprehensions offer a concise way to create lists. When it comes to initializing a list of dictionaries, a list comprehension can be used to streamline the process and condense the code that would otherwise be written as a for loop.

This snippet achieves the same result as Method 1 but in a more compact form using list comprehension. Each iteration of the loop inside the list comprehension generates a dictionary, which is then automatically appended to the resulting list users . This method is more Pythonic and is great for lines of code reduction and readability, but it can be less clear to Python newcomers.

Method 3: Using the * Operator

Python’s * operator can be used to repeat items in a list. To initialize a list of identical dictionaries without manually copying them, the * operator can be quite efficient; however, it creates shallow copies, so care should be taken when the dictionaries will be modified.

Here, instead of individually creating each dictionary, we define a template dictionary and use list comprehension with the .copy() method to create individual copies for each item in the list users . This approach is useful when starting with a default structure, but it requires further individual updates if each dictionary is to differ from the template.

Method 4: Using the dict() Constructor

The dict() constructor can be used to convert sequences containing key-value pairs into dictionaries. This method is particularly useful for creating dictionaries with a common set of keys.

This code first creates a list of tuples with the values for each dictionary. Then, it uses the dict() constructor along with zip() to combine these values with the common set of keys inside a list comprehension. The result is a list of dictionaries with the same keys but different values. It’s a neat method for ensuring consistency of keys across dictionaries.

Bonus One-Liner Method 5: Dictionary Comprehensions

Dictionary comprehensions, similar to list comprehensions, allow for the direct creation of dictionaries. A list of dictionary comprehensions can also be used to create a list of dictionaries in a concise one-liner.

This snippet uses a dictionary comprehension within a list comprehension to generate individual dictionaries. It dynamically constructs keys and values based on the iteration variable. This method is slick and Pythonic, but the complexity might be a bit high if the code needs to be understood by novices.

Summary/Discussion

  • Method 1: For Loop. Easy to understand. Best for variable dictionary content. Can be verbose.
  • Method 2: List Comprehension. Compact. Pythonic. Might be less clear for beginners.
  • Method 3: Using * Operator with .copy() . Good for initializing default structures. Requires additional steps for unique elements.
  • Method 4: dict() Constructor. Ensures consistency of keys. Might be less straightforward for complex structures.
  • Method 5: Dictionary Comprehension. Very concise. Can handle complex constructions. Not as beginner-friendly.

Emily Rosemary Collins is a tech enthusiast with a strong background in computer science, always staying up-to-date with the latest trends and innovations. Apart from her love for technology, Emily enjoys exploring the great outdoors, participating in local community events, and dedicating her free time to painting and photography. Her interests and passion for personal growth make her an engaging conversationalist and a reliable source of knowledge in the ever-evolving world of technology.

  • Docs »
  • Chapter 3 - Lists, Tuples and Dictionaries
  • View page source

Chapter 3 - Lists, Tuples and Dictionaries ¶

Python has several other important data types that you’ll probably use every day. They are called lists, tuples and dictionaries. This chapter’s aim is to get you acquainted with each of these data types. They are not particularly complicated, so I expect that you will find learning how to use them very straight forward. Once you have mastered these three data types plus the string data type from the previous chapter, you will be quite a ways along in your education of Python. You’ll be using these four building blocks in 99% of all the applications you will write.

A Python list is similar to an array in other languages. In Python, an empty list can be created in the following ways.

As you can see, you can create the list using square brackets or by using the Python built-in, list . A list contains a list of elements, such as strings, integers, objects or a mixture of types. Let’s take a look at some examples:

The first list has 3 integers, the second has 3 strings and the third has a mixture. You can also create lists of lists like this:

Occasionally, you’ll want to combine two lists together. The first way is to use the extend method:

A slightly easier way is to just add two lists together.

Yes, it really is that easy. You can also sort a list. Let’s spend a moment to see how to do that:

Now there is a got-cha above. Can you see it? Let’s do one more example to make it obvious:

In this example, we try to assign the sorted list to a variable. However, when you call the sort() method on a list, it sorts the list in-place. So if you try to assign the result to another variable, then you’ll find out that you’ll get a None object, which is like a Null in other languages. Thus when you want to sort something, just remember that you sort them in-place and you cannot assign it to a different variable.

You can slice a list just like you do with a string:

This code returns a list of just the first 3 elements.

A tuple is similar to a list, but you create them with parentheses instead of square brackets. You can also use the tuple built-in. The main difference is that a tuple is immutable while the list is mutable. Let’s take a look at a few examples:

The code above demonstrates one way to create a tuple with five elements. It also shows that you can do tuple slicing. However, you cannot sort a tuple! The last two examples shows how to create tuples using the tuple keyword. The first one just creates an empty tuple whereas the second example has three elements inside it. Notice that it has a list inside it. This is an example of casting . We can change or cast an item from one data type to another. In this case, we cast a list into a tuple. If you want to turn the abc tuple back into a list, you can do the following:

To reiterate, the code above casts the tuple (abc) into a list using the list function.

Dictionaries ¶

A Python dictionary is basically a hash table or a hash mapping. In some languages, they might be referred to as associative memories or associative arrays . They are indexed with keys, which can be any immutable type. For example, a string or number can be a key. You need to be aware that a dictionary is an unordered set of key:value pairs and the keys must be unique. You can get a list of keys by calling a dictionary instance’s keys method. To check if a dictionary has a key, you can use Python’s in keyword. In some of the older versions of Python (2.3 and older to be specific), you will see the has_key keyword used for testing if a key is in a dictionary. This keyword is deprecated in Python 2.x and removed entirely from Python 3.x.

Let’s take a moment to see how we create a dictionary.

The first two examples show how to create an empty dictionary. All dictionaries are enclosed with curly braces. The last line is printed out so you can see how unordered a dictionary is. Now it’s time to find out how to access a value in a dictionary.

In the first example, we use the dictionary from the previous example and pull out the value associated with the key called “one”. The second example shows how to acquire the value for the “name” key. Now let’s see how to tell if a key is in a dictionary or not:

So, if the key is in the dictionary, Python returns a Boolean True . Otherwise it returns a Boolean False . If you need to get a listing of all the keys in a dictionary, then you do this:

In Python 2, the keys method returns a list. But in Python 3, it returns a view object . This gives the developer the ability to update the dictionary and the view will automatically update too. Also note that when using the in keyword for dictionary membership testing, it is better to do it against the dictionary instead of the list returned from the keys method. See below:

While this probably won’t matter much to you right now, in a real job situation, seconds matter. When you have thousands of files to process, these little tricks can save you a lot of time in the long run!

Wrapping Up ¶

In this chapter you just learned how to construct a Python list, tuple and dictionary. Make sure you understand everything in this section before moving on. These concepts will assist you in designing your programs. You will be building complex data structures using these building blocks every day if you choose to pursue employment as a Python programmer. Each of these data types can be nested inside the others. For example, you can have a nested dictionary, a dictionary of tuples, a tuple made up of several dictionaries, and on and on.

When you are ready to move on, we will learn about Python’s support for conditional statements.

  • Learn Python
  • Python Lists
  • Python Dictionaries
  • Python Strings
  • Python Functions
  • Learn Pandas & NumPy
  • Pandas Tutorials
  • Numpy Tutorials
  • Learn Data Visualization
  • Python Seaborn
  • Python Matplotlib

Python Dictionaries: A Complete Overview

  • December 10, 2021 December 27, 2023

Python dictionaries are an incredibly useful data type, which allow you to store data in key:value pairs. In this tutorial, you’ll learn all you need to know to get up and running with Python dictionaries, including:

  • The basics of creating dictionaries to store and access data
  • What the best use cases for dictionaries are
  • Adding and removing data from dictionaries
  • How to apply functions and methods to dictionaries

Let’s get started!

Table of Contents

What are Python Dictionaries?

Python dictionaries are container data types, like Python lists. Dictionaries use a key-value pair mapping, allowing you to retrieve a value by looking up its corresponding key. They are very similar to what, in other programming languages, is called an associative array. This is because it’s an array of data that is associated to something else – in this case, a key.

Unlike Python lists, which are sequence data types, Python dictionaries work a little differently. Because lists are sequenced, we can access items based on their position. For example, to access a particular item in a Python list, we can simply reference its index:

Because Python dictionaries aren’t a sequence data type, we can’t simply access, say, the first item. In order to access a particular value in a Python dictionary, we use a key in the dictionary to access the value.

In a Python dictionary, you can have multiple keys. These keys must be:

  • Unique – a given key can only exist a single time
  • Immutable – meaning that keys must be of data types that cannot be altered, such as strings

Think of Python dictionaries as, well, dictionaries. You can look up the value of a word (i.e., a key) and it’ll give you the corresponding definition (i.e., its value).

Creating a Python Dictionary

Let’s take a look at how we can create a Python dictionary. To start off, we’ll create an empty dictionary. We have two main ways of accomplishing this:

We can check the type of these dictionaries by using the built-in type() function:

Similarly, we can load a populated dictionary by loading it directly. Let’s take a look at how this looks by loading a dictionary with a person’s attributes:

We can see we were able to embed quite a few different items as values here. To name a few, we have an integer (representing an age), strings (representing, say, a location), and even lists!

You don’t actually need to write this out across separate lines, but it’s much easier to read. We could have accomplished the same thing by simply writing:

Now that you have a strong understanding of how to create Python dictionaries, let’s take a look at how to use them.

How Are Dictionaries Related to Data Science?

At this point, you may be wondering how dictionaries are related to data science? When we access data from the web it often comes in a format know as JSON ( J ava S cript O bject N otation). This format very closely resembles the format of Python dictionaries.

Knowing how to work with Python dictionaries allows us to easily download data from the web and manipulate it. The format is incredibly common and will offer up significantly higher flexibility in terms of accessing and working with data from different sources.

Working with Python Dictionaries

Being able to create Python dictionaries is one thing, but you also need to know how to work with them. In this section, you’ll learn different ways of accessing dictionary items, modify items, and how to add and remove items. There are different ways in which to accomplish all of this but you’ll learn the safest and most common ways of accomplish this.

Accessing Items in Python Dictionaries

There are two main ways in which we can access items inside of a dictionary. We can use square brackets, [] , similar to accessing a list item using its index. We can also use the .get() method.

Let’s take a look at how we can use the square brackets to access an item.

That was easy! One of the quirks of using the square brackets method of accessing items is that it doesn’t work well with items that don’t exist.

Try running the code below to access an item that doesn’t exist, such as 'hobbies' to see what happens:

We can see that when we try to access an item that doesn’t exist that a KeyError is thrown. This indicates to us that a key doesn’t exist. What’s worse is that this actually crashes our program (unless we explicitly handle that error).

One way that we can work around this is by using the .get() method. The .get() method will simply return the None value when a key doesn’t exist.

The method works by applying it to a dictionary and passing in the key for which we want to return the value. Let’s see how we can use this to return the value for 'name' :

One of the perks of using the .get() method is that we can even pass in a default value that we want returned when a key doesn’t exist. For example, say we had intended to have a key named 'hobbies' which would contain a list of different hobbies. Instead of returning None , we could ask Python to return an empty list.

See if you can write the code below to make this happen. The solution is accessible by selecting the toggle:

A Potential Solution

# Getting Dictionary Items that don't exist

info = { 'name': 'Nik', 'age': 33, 'location': 'Toronto' }

print(info.get('hobbies', []))

Adding Items to Python Dictionaries

Adding items to a Python dictionary is incredibly easy! We can simply directly assign a key:value pair onto the dictionary.

Let’s see what this looks like. We’ll want to add an item of hobbies into our dictionary.

Python also provides a number of ways to merge two dictionaries together. This can be incredibly helpful if data has been collected separately and you don’t want to manually update items in one dictionary with the items of another.

For this, we can use the .update() method. Similarly, we can use the | operator in Python 3.8+. Both these methods work in the same way, in that the dictionary on the right will merge into the dictionary on the left. Any new key-value pairs will be added, while any existing keys in the left dictionary will be updated with values on the right.

We can see that new items from the more_info dictionary were added, while existing items were updated. Keep this in mind as you update information!

Modifying Existing Python Dictionary Items

Modifying existing items works the same as adding new ones! We can simply directly assign a value to an existing key and update its value. The added benefit of this is that if an item doesn’t exist, that a new one gets added.

Let’s take a look at adding modifying our key 'location' key in our dictionary:

There’s not much more to this! Let’s take a look at how to remove items from a Python dictionary.

Removing Items from Python Dictionaries

Similar to lists, Python provides a number of different ways to remove items from dictionaries. The first approach we’ll take a look at is the del keyword. The keyword accepts a dictionary item and removes the item from the dictionary.

Let’s see how we can use the keyword to delete an item:

We can also use the Python .pop() method to remove an item from a dictionary. The benefit of this approach is that it returns the value before removing the key-value pair. Let’s see what this looks like:

With both of these methods, we need to be careful to not remove keys that don’t exist. Both of these methods will return a KeyError if we try to delete a key that doesn’t exist. Let’s confirm this:

The .pop() method does allow us to provide a default value so that your program doesn’t crash when a key doesn’t exist. This allows us to run the program more safely.

Let’s see how this works:

While, of course, this doesn’t delete the key, it allows us to more safely write programs that require accessing and removing a key from a dictionary.

Python Dictionary Methods

Python dictionaries provide many different methods – you’ve even already learned a few of them! In this section, you’ll learn a few more that allow you to access the keys and values of dictionaries.

Accessing Dictionary Items with .items()

We can use the .items() method to easily retrieve all of the items in a dictionary. Applying this method returns a list-like object that contains tuples containing the key and the value of each item in the dictionary.

This can be incredibly helpful if you want to loop over the keys and the values. Let’s see what this looks like:

We can iterate over this dict_items object in order to access both the keys and the values. You’ll learn this in the following section on iterating through dictionaries .

Accessing Dictionary Keys with .keys()

We can easily access all the keys in a dictionary by using the .keys() method. This returns a list-like object that contains allow of the keys.

Let’s take our earlier dictionary and apply the .keys() method:

Accessing Dictionary Values with .values()

Similar to the .keys() method, we’re able to access all the values in a Python dictionary using the .items() method. This also returns a list-like object that contains the values of all keys in a dictionary.

Let’s apply the .items() method to our dictionary:

Checking Membership in Python Dictionaries

We can easily check for membership in a Python dictionary by using the in keyword. Let’s see how we can see if a key exists in a Python dictionary by using the .keys() method:

We can actually simplify this process by not using the .keys() method. By default, Python will check for membership in the keys of a dictionary. Because of this, we can even drop the method from our membership check:

In the next section you’ll learn how to iterate through Python dictionaries.

Iterating through Python Dictionaries

Now that you have a strong understanding of how to access items, keys and values in Python dictionaries. Let’s take a look at how we can iterate over Python dictionaries.

Because the .items() , .keys() , and .values() methods all return list-like objects, we can iterate over them directly. Let’s take a look at how to iterate over the keys first:

This approach works the same for .items() .

But what if you wanted to iterate over the keys and values in one go. For this, you can use what’s known as unpacking . We can iterate over the .items() method return and unpack the key and value from the returned tuple.

Let’s see what this looks like:

In the final section below, you’ll learn whether or not Python dictionaries are ordered or not.

Are Python Dictionaries Ordered?

Answering whether Python dictionaries are ordered or not is not a simple yes or no. Prior to version 3.6 of Python, dictionaries were unordered. Beginning in Python 3.6 (and more formally so in Python 3.7), Python dictionaries are ordered.

What does this mean? Python dictionaries are now ordered based on the insertion order . The benefit of this is faster retrieval.

Below you’ll find a couple of exercises to help you check your understanding of Python dictionaries. Use the code workspace provided to test your solutions. You can toggle the sections to check the solutions.

Create a dictionary like the one below and complete the following exercises:

Print out all the values of the dictionary using a for loop .

Add a new key that contains a list of values .

Update the location key to ‘Vancouver’ .

Conclusion and Recap

Phew! You made it to the end of the tutorial! There was a lot to learn about Python dictionaries and you’ve learned a ton about them!

Below, you’ll find a quick recap of everything you learned about Python dictionaries:

  • Dictionaries are an associative array of values containing key-value pairs
  • Keys must be immutable and unique
  • Values can be any type of value and can be duplicated
  • You can create dictionaries with the use of the dict() function or curly braces {}
  • Dictionaries are similar to the JSON format which is often used to store data on the internet
  • We can add items by simply assigning a value to a key
  • We can delete items using del or .pop()
  • The .pop() method allows us to pass in a default value which allows our program to run safely if a key doesn’t exist
  • We can access items using the .items() , .keys() , and .values() methods

Additional Resources

Check out the tutorials below for some additional resources:

  • Python: Sort a Dictionary by Values
  • Python Merge Dictionaries – Combine Dictionaries (7 Ways)
  • Python: Pretty Print a Dict (Dictionary) – 4 Ways
  • Python: Get Dictionary Key with the Max Value (4 Ways)
  • Official Documentation on Python dictionaries

Nik Piepenbreier

Nik is the author of datagy.io and has over a decade of experience working with data analytics, data science, and Python. He specializes in teaching developers how to use Python for data science using hands-on tutorials. View Author posts

6 thoughts on “Python Dictionaries: A Complete Overview”

Man this website turned out a charm for me. I can’t express how much I learn in these 6 days. I hope you (nik) will upload such interesting and amazing python and data science articles and tutorials. Thanks Nik

Thank you SO much Madhur! That made my day! I have lots more content and refinement coming :).

Day 7, done. This tutorial is excelente! 🙂

I’m so glad you’re enjoying it!!

Nik, sorry to bother you, but I find that using the union operator (|) without re-assign it to another dictionary actually happens in place too as same as the update() method. Did I misinterpret your meaning?

Hi Zeyu! Thanks so much for your comment! I have updated the article to reflect this – thank you for flagging it!

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Save my name, email, and website in this browser for the next time I comment.

python list dictionary assignment

  • Table of Contents
  • Course Home
  • Assignments
  • Peer Instruction (Instructor)
  • Peer Instruction (Student)
  • Change Course
  • Instructor's Page
  • Progress Page
  • Edit Profile
  • Change Password
  • Scratch ActiveCode
  • Scratch Activecode
  • Instructors Guide
  • About Runestone
  • Report A Problem
  • Mixed-Up Code Questions
  • Write Code Questions
  • Peer Instruction: Tuples Multiple Choice Questions
  • 11.1 Tuples are Immutable
  • 11.2 Comparing Tuples
  • 11.3 Tuple Assignment
  • 11.4 Dictionaries and Tuples
  • 11.5 Multiple Assignment with Dictionaries
  • 11.6 The Most Common Words
  • 11.7 Using Tuples as Keys in Dictionaries
  • 11.8 Sequences: Strings, Lists, and Tuples - Oh My!
  • 11.9 Debugging
  • 11.10 Glossary
  • 11.11 Multiple Choice Questions
  • 11.12 Tuples Mixed-Up Code Questions
  • 11.13 Write Code Questions
  • 11.4. Dictionaries and Tuples" data-toggle="tooltip">
  • 11.6. The Most Common Words' data-toggle="tooltip" >

11.5. Multiple Assignment with Dictionaries ¶

By combining items , tuple assignment, and for , you can make a nice code pattern for traversing the keys and values of a dictionary in a single loop:

This loop has two iteration variables because items returns a list of tuples and key, val is a tuple assignment that successively iterates through each of the key-value pairs in the dictionary.

For each iteration through the loop, both key and value are advanced to the next key-value pair in the dictionary (still in hash order).

The output of this loop is:

Again, it is in hash key order (i.e., no particular order).

11-9-1: How will the contents of list “lst” be ordered after the following code is run?

  • [(4, 'd'), (10, 'a'), (15, 'b'), (17, 'c')]
  • Incorrect! Remember, key-value pairs aren't in any particular order. Try again.
  • [('a', 10), ('b', 15), ('c', 17), ('d', 4)]
  • There will be no particular order
  • Correct! When running this type of iteration, we are left with a hash key order, meaning there is no particular order.

If we combine these two techniques, we can print out the contents of a dictionary sorted by the value stored in each key-value pair.

To do this, we first make a list of tuples where each tuple is (value, key) . The items method would give us a list of (key, value) tuples, but this time we want to sort by value, not key. Once we have constructed the list with the value-key tuples, it is a simple matter to sort the list in reverse order and print out the new, sorted list.

By carefully constructing the list of tuples so that the value is the first element of each tuple and the key is the second element, we can sort our dictionary contents by value.

Construct a block of code to iterate through the items in dictionary d and print out its key-value pairs.

Write code to create a list called ‘lst’ and add the key-value pairs of dictionary d to list lst as tuples. Sort list lst by the values in descending order.

  • Python Basics
  • Interview Questions
  • Python Quiz
  • Popular Packages
  • Python Projects
  • Practice Python
  • AI With Python
  • Learn Python3
  • Python Automation
  • Python Web Dev
  • DSA with Python
  • Python OOPs
  • Dictionaries

Python Operators

Precedence and associativity of operators in python.

  • Python Arithmetic Operators
  • Difference between / vs. // operator in Python
  • Python - Star or Asterisk operator ( * )
  • What does the Double Star operator mean in Python?
  • Division Operators in Python
  • Modulo operator (%) in Python
  • Python Logical Operators
  • Python OR Operator
  • Difference between 'and' and '&' in Python
  • not Operator in Python | Boolean Logic

Ternary Operator in Python

  • Python Bitwise Operators

Python Assignment Operators

Assignment operators in python.

  • Walrus Operator in Python 3.8
  • Increment += and Decrement -= Assignment Operators in Python
  • Merging and Updating Dictionary Operators in Python 3.9
  • New '=' Operator in Python3.8 f-string

Python Relational Operators

  • Comparison Operators in Python
  • Python NOT EQUAL operator
  • Difference between == and is operator in Python
  • Chaining comparison operators in Python
  • Python Membership and Identity Operators
  • Difference between != and is not operator in Python

In Python programming, Operators in general are used to perform operations on values and variables. These are standard symbols used for logical and arithmetic operations. In this article, we will look into different types of Python operators. 

  • OPERATORS: These are the special symbols. Eg- + , * , /, etc.
  • OPERAND: It is the value on which the operator is applied.

Types of Operators in Python

  • Arithmetic Operators
  • Comparison Operators
  • Logical Operators
  • Bitwise Operators
  • Assignment Operators
  • Identity Operators and Membership Operators

Python Operators

Arithmetic Operators in Python

Python Arithmetic operators are used to perform basic mathematical operations like addition, subtraction, multiplication , and division .

In Python 3.x the result of division is a floating-point while in Python 2.x division of 2 integers was an integer. To obtain an integer result in Python 3.x floored (// integer) is used.

Example of Arithmetic Operators in Python

Division operators.

In Python programming language Division Operators allow you to divide two numbers and return a quotient, i.e., the first number or number at the left is divided by the second number or number at the right and returns the quotient. 

There are two types of division operators: 

Float division

  • Floor division

The quotient returned by this operator is always a float number, no matter if two numbers are integers. For example:

Example: The code performs division operations and prints the results. It demonstrates that both integer and floating-point divisions return accurate results. For example, ’10/2′ results in ‘5.0’ , and ‘-10/2’ results in ‘-5.0’ .

Integer division( Floor division)

The quotient returned by this operator is dependent on the argument being passed. If any of the numbers is float, it returns output in float. It is also known as Floor division because, if any number is negative, then the output will be floored. For example:

Example: The code demonstrates integer (floor) division operations using the // in Python operators . It provides results as follows: ’10//3′ equals ‘3’ , ‘-5//2’ equals ‘-3’ , ‘ 5.0//2′ equals ‘2.0’ , and ‘-5.0//2’ equals ‘-3.0’ . Integer division returns the largest integer less than or equal to the division result.

Precedence of Arithmetic Operators in Python

The precedence of Arithmetic Operators in Python is as follows:

  • P – Parentheses
  • E – Exponentiation
  • M – Multiplication (Multiplication and division have the same precedence)
  • D – Division
  • A – Addition (Addition and subtraction have the same precedence)
  • S – Subtraction

The modulus of Python operators helps us extract the last digit/s of a number. For example:

  • x % 10 -> yields the last digit
  • x % 100 -> yield last two digits

Arithmetic Operators With Addition, Subtraction, Multiplication, Modulo and Power

Here is an example showing how different Arithmetic Operators in Python work:

Example: The code performs basic arithmetic operations with the values of ‘a’ and ‘b’ . It adds (‘+’) , subtracts (‘-‘) , multiplies (‘*’) , computes the remainder (‘%’) , and raises a to the power of ‘b (**)’ . The results of these operations are printed.

Note: Refer to Differences between / and // for some interesting facts about these two Python operators.

Comparison of Python Operators

In Python Comparison of Relational operators compares the values. It either returns True or False according to the condition.

= is an assignment operator and == comparison operator.

Precedence of Comparison Operators in Python

In Python, the comparison operators have lower precedence than the arithmetic operators. All the operators within comparison operators have the same precedence order.

Example of Comparison Operators in Python

Let’s see an example of Comparison Operators in Python.

Example: The code compares the values of ‘a’ and ‘b’ using various comparison Python operators and prints the results. It checks if ‘a’ is greater than, less than, equal to, not equal to, greater than, or equal to, and less than or equal to ‘b’ .

Logical Operators in Python

Python Logical operators perform Logical AND , Logical OR , and Logical NOT operations. It is used to combine conditional statements.

Precedence of Logical Operators in Python

The precedence of Logical Operators in Python is as follows:

  • Logical not
  • logical and

Example of Logical Operators in Python

The following code shows how to implement Logical Operators in Python:

Example: The code performs logical operations with Boolean values. It checks if both ‘a’ and ‘b’ are true ( ‘and’ ), if at least one of them is true ( ‘or’ ), and negates the value of ‘a’ using ‘not’ . The results are printed accordingly.

Bitwise Operators in Python

Python Bitwise operators act on bits and perform bit-by-bit operations. These are used to operate on binary numbers.

Precedence of Bitwise Operators in Python

The precedence of Bitwise Operators in Python is as follows:

  • Bitwise NOT
  • Bitwise Shift
  • Bitwise AND
  • Bitwise XOR

Here is an example showing how Bitwise Operators in Python work:

Example: The code demonstrates various bitwise operations with the values of ‘a’ and ‘b’ . It performs bitwise AND (&) , OR (|) , NOT (~) , XOR (^) , right shift (>>) , and left shift (<<) operations and prints the results. These operations manipulate the binary representations of the numbers.

Python Assignment operators are used to assign values to the variables.

Let’s see an example of Assignment Operators in Python.

Example: The code starts with ‘a’ and ‘b’ both having the value 10. It then performs a series of operations: addition, subtraction, multiplication, and a left shift operation on ‘b’ . The results of each operation are printed, showing the impact of these operations on the value of ‘b’ .

Identity Operators in Python

In Python, is and is not are the identity operators both are used to check if two values are located on the same part of the memory. Two variables that are equal do not imply that they are identical. 

Example Identity Operators in Python

Let’s see an example of Identity Operators in Python.

Example: The code uses identity operators to compare variables in Python. It checks if ‘a’ is not the same object as ‘b’ (which is true because they have different values) and if ‘a’ is the same object as ‘c’ (which is true because ‘c’ was assigned the value of ‘a’ ).

Membership Operators in Python

In Python, in and not in are the membership operators that are used to test whether a value or variable is in a sequence.

Examples of Membership Operators in Python

The following code shows how to implement Membership Operators in Python:

Example: The code checks for the presence of values ‘x’ and ‘y’ in the list. It prints whether or not each value is present in the list. ‘x’ is not in the list, and ‘y’ is present, as indicated by the printed messages. The code uses the ‘in’ and ‘not in’ Python operators to perform these checks.

in Python, Ternary operators also known as conditional expressions are operators that evaluate something based on a condition being true or false. It was added to Python in version 2.5. 

It simply allows testing a condition in a single line replacing the multiline if-else making the code compact.

Syntax :   [on_true] if [expression] else [on_false] 

Examples of Ternary Operator in Python

The code assigns values to variables ‘a’ and ‘b’ (10 and 20, respectively). It then uses a conditional assignment to determine the smaller of the two values and assigns it to the variable ‘min’ . Finally, it prints the value of ‘min’ , which is 10 in this case.

In Python, Operator precedence and associativity determine the priorities of the operator.

Operator Precedence in Python

This is used in an expression with more than one operator with different precedence to determine which operation to perform first.

Let’s see an example of how Operator Precedence in Python works:

Example: The code first calculates and prints the value of the expression 10 + 20 * 30 , which is 610. Then, it checks a condition based on the values of the ‘name’ and ‘age’ variables. Since the name is “ Alex” and the condition is satisfied using the or operator, it prints “Hello! Welcome.”

Operator Associativity in Python

If an expression contains two or more operators with the same precedence then Operator Associativity is used to determine. It can either be Left to Right or from Right to Left.

The following code shows how Operator Associativity in Python works:

Example: The code showcases various mathematical operations. It calculates and prints the results of division and multiplication, addition and subtraction, subtraction within parentheses, and exponentiation. The code illustrates different mathematical calculations and their outcomes.

To try your knowledge of Python Operators, you can take out the quiz on Operators in Python . 

Python Operator Exercise Questions

Below are two Exercise Questions on Python Operators. We have covered arithmetic operators and comparison operators in these exercise questions. For more exercises on Python Operators visit the page mentioned below.

Q1. Code to implement basic arithmetic operations on integers

Q2. Code to implement Comparison operations on integers

Explore more Exercises: Practice Exercise on Operators in Python

Please Login to comment...

Similar reads.

  • python-basics
  • Python-Operators

Improve your Coding Skills with Practice

 alt=

What kind of Experience do you want to share?

Python Tutorial

File handling, python modules, python numpy, python pandas, python matplotlib, python scipy, machine learning, python mysql, python mongodb, python reference, module reference, python how to, python examples, python dictionaries.

Dictionaries are used to store data values in key:value pairs.

A dictionary is a collection which is ordered*, changeable and do not allow duplicates.

As of Python version 3.7, dictionaries are ordered . In Python 3.6 and earlier, dictionaries are unordered .

Dictionaries are written with curly brackets, and have keys and values:

Create and print a dictionary:

Dictionary Items

Dictionary items are ordered, changeable, and do not allow duplicates.

Dictionary items are presented in key:value pairs, and can be referred to by using the key name.

Print the "brand" value of the dictionary:

Ordered or Unordered?

When we say that dictionaries are ordered, it means that the items have a defined order, and that order will not change.

Unordered means that the items do not have a defined order, you cannot refer to an item by using an index.

Dictionaries are changeable, meaning that we can change, add or remove items after the dictionary has been created.

Duplicates Not Allowed

Dictionaries cannot have two items with the same key:

Duplicate values will overwrite existing values:

Advertisement

Dictionary Length

To determine how many items a dictionary has, use the len() function:

Print the number of items in the dictionary:

Dictionary Items - Data Types

The values in dictionary items can be of any data type:

String, int, boolean, and list data types:

From Python's perspective, dictionaries are defined as objects with the data type 'dict':

Print the data type of a dictionary:

The dict() Constructor

It is also possible to use the dict() constructor to make a dictionary.

Using the dict() method to make a dictionary:

Python Collections (Arrays)

There are four collection data types in the Python programming language:

  • List is a collection which is ordered and changeable. Allows duplicate members.
  • Tuple is a collection which is ordered and unchangeable. Allows duplicate members.
  • Set is a collection which is unordered, unchangeable*, and unindexed. No duplicate members.
  • Dictionary is a collection which is ordered** and changeable. No duplicate members.

*Set items are unchangeable, but you can remove and/or add items whenever you like.

**As of Python version 3.7, dictionaries are ordered . In Python 3.6 and earlier, dictionaries are unordered .

When choosing a collection type, it is useful to understand the properties of that type. Choosing the right type for a particular data set could mean retention of meaning, and, it could mean an increase in efficiency or security.

Get Certified

COLOR PICKER

colorpicker

Contact Sales

If you want to use W3Schools services as an educational institution, team or enterprise, send us an e-mail: [email protected]

Report Error

If you want to report an error, or if you want to make a suggestion, send us an e-mail: [email protected]

Top Tutorials

Top references, top examples, get certified.

Do assignments ever require locking?

I recently came across some code where the author applies locks around “simple” assignments, in a multithreaded program:

I.e. the lock merely protects reading and writing the member variable.

Is there any situation, maybe in pypy or some other non-CPython implementation of Python, where the above code might be required to avoid a race condition?

The author of the code in question doesn’t want to remove the lock because they think it might be necessary on Jython or pypy or a future no-GIL CPython or [unknown].

My take is that assignments are atomic by definition, no matter the underlying Python implementation, and the lock is unnecessary overhead and impedes the code’s readability.

Who is correct?

I’d agree with you for reading a primitive.

In the code example, without the lock multiple threads could write to that method variable. And presumably it’s not about reading that method variable (like a primitive). It’s called call_back so the intention is to call it. This could do anything to other state on obj, and require other expensive or shared resources.

So the author could well have had good reason. If nothing’s broken, I would not mess around with it just to improve code quality.

My understanding is that assignments are not by definition atomic - that they are only atomic for simple assignments (using immutable objects like small integers or using built-in data types). Assignments for mutable types/complex objects correspond to multiple byte code instructions. My understanding that a thread switch can occur between any two byte code instructions.

I tried to find a good reference in the official Python docs. Best I could find was this: What kind of global mutation are thread-safe? which is rather fuzzy.

I’m not sure, but I’m tempted to think the sample code does require locking (if thread-safety is a goal). The lock on the read could in some cases also be required, I think. Perhaps not in this example (I dont know), what if you have a longer block of code where the function would be called multiple times and you want to ensure consistency? Also, ‘some_callback’ itself would make me nervous, since it can be anything – for instance a C-level call that itself releases the GIL; it could by itself be thread-safe, but once it releases the GIL anyone is free to modify the parent object.

Unfortunately, without being completely sure what the object is, we can’t actually say. If some_callback is actually a property, it could do anything (as it’s effectively a method call in disguise). Personally I would consider this to be bad style (if it’s a property and it absolutely needs atomicity, it should do the locking inside the property function instead), but it’s legal.

But my gut feeling is that this is cargo cult programming. Having run into threading problems and solved them with locks, the author threw them into more places. It’s really hard to be completely sure, though.

Let’s assume that obj.some_callback is not a property; if it was it could lock itself internally. Likewise if there was an issue with the callback getting run from two threads then it could use an internal lock if it needed to.

My question thus boils down to this: Can “thread A updates an attribute while thread B reads it” result in any other outcome than “thread B reads either the old or the new value of the attribute” plus “there are no related consistency problems” (like broken reference counters)? Or, more to the point, does the specification of Python-the-language, as far as such specification exists, guarantee that anywhere?

No, there is no such formal python specification. However, by default CPython’s behavior is then what should be expected from all implementations, which in this case clearly says “no, pure python code should never be able to result in broken (e.g. wrong ref count) objects”

Starting with the last question: We’re currently (as of 2024) actually seeing quite a bit of specification needing to be written. Aspects that had previously not required any sort of documentation are now going to become important. Free threading is revealing that there are definitely some aspects of Python-the-language that have never actually been promised, and CPython implementation details are what we all go on. So, take all of what I say, and all of what everyone else in this thread says, with the proviso that more things may be specified in the future. I would generally assume that any new specs will be compatible with existing behaviour, though, so anything that IS specified should remain valid.

So. Let’s figure out exactly what happens when you mutate an object’s aftribute. As mentioned, properties and such can get in the way, but I’m going to assume the most simple and straight-forward behaviour there is: The object’s dictionary gets updated.

So your question comes down to two things:

  • Can thread A and thread B see two distinct dictionaries?
  • If one thread is changing a dictionary, will another thread see problems?

I’ll start by excluding a number of behaviours which, if they were to occur, would definitely be called interpreter bugs:

  • A “half-and-half” pointer error. On some CPU architectures, a pointer (such as a Python object reference) can’t be written in one go, so you have to write one half, then the other half. So you could read the first half of the new value paired with the second half of the old value, which would give you a nonsense pointer. This would be bad, very very bad; but it would also be one of the most obvious problems to look for. I think we can rule this one out on the basis that the exact same problem will show up in practically everything, and so it will NEED to be solved. (Which is quite easy on those CPU architectures that can write an entire pointer atomically.)
  • A broken reference count. This one’s specific to reference counting, obviously, and one way to prevent it is to go for a different style of garbage collection (Python doesn’t mandate refcounting). But, again, if refcounting is a thing, broken refcounts are a critical failure, so this one will be dealt with.
  • A failure within the dictionary itself. For example, thread A might be trying to add a new attribute, which causes the dictionary to enlarge itself. This would be a more insidious bug as it’s not going to trigger nearly as frequently as the other types, but since dictionaries are so important in Python, I would trust that people smarter than I will have already looked into this and made sure it won’t be a problem. (Which, again, might be quite simple if there’s a way to leave the old dictionary contents visible to other threads while the new hash table is being constructed.)

In general, anything that would outright segfault the interpreter should be considered a bug. [1] Bugs definitely do happen, but the more common the situation, the more likely that it’ll be discovered early. Core data types like dictionaries, lists, strings, etc should be safe from these kinds of critical failures.

That’s not to say there can’t be other sorts of errors, and a simple x += 1 could well produce strange results, but at very very least, it won’t result in a memory leak or a half-and-half pointer or anything like that.

Unless you’re using ctypes - in which case, have fun, there’s endless crashes waiting for you! ↩︎

The GIL ensures that python will be able to execute its byte code ops atomically. The lock is pointless, unless its a property. As Chris suggest may be cargo-culted.

If there was a read-modify-write pattern then a lock is mandatory for correctness.

If 2 threads read the some_callback then there is nothing to stop the callback being invoken by both threads. Which may, or may not, be intended. More of the design would need be explained.

(This is a decent approximation, but there are exceptions. The GIL isn’t held for “one bytecode operation”; but you can certainly assume that the GIL could be released between any two operations as listed in dis.dis() .)

Umm, well, there are Python versions without a GIL today, not to mention the current work to remove it entirely, long-term.

There will need to be an equivalent guarantee spelled out that we can reason about for multi-threaded code for the free-threading python.

Which, I assume, will be documented at some point.

Related Topics

IMAGES

  1. 8 Ways To Create Python Dictionary Of Lists

    python list dictionary assignment

  2. Python Collections

    python list dictionary assignment

  3. How to Append a Dictionary to a List in Python • datagy

    python list dictionary assignment

  4. How to create a List of Dictionaries in Python?

    python list dictionary assignment

  5. Python Dictionary

    python list dictionary assignment

  6. Python Dictionary Values To List

    python list dictionary assignment

VIDEO

  1. PYTHON

  2. Python Tutorial : Dictionary in Python

  3. P29

  4. Python Dictionary Essentials: Creation and Manipulation

  5. Mutable & Immutable Data Types in Python ~ list ~ dictionary ~ string ~ Introduction to Python

  6. Dictionary in Python

COMMENTS

  1. 5. Data Structures

    The del statement can also be used to remove slices from a list or clear the entire list (which we did earlier by assignment of an empty list to the slice). For example: >>> a = ... Another useful data type built into Python is the dictionary (see Mapping Types — dict). Dictionaries are sometimes found in other languages as "associative ...

  2. Python Dictionary Exercise with Solution [10 Exercise Questions]

    Table of contents. Exercise 1: Convert two lists into a dictionary. Exercise 2: Merge two Python dictionaries into one. Exercise 3: Print the value of key 'history' from the below dict. Exercise 4: Initialize dictionary with default values. Exercise 5: Create a dictionary by extracting the keys from a given dictionary.

  3. Python's list Data Type: A Deep Dive With Examples

    Python's list is a flexible, versatile, powerful, and popular built-in data type. It allows you to create variable-length and mutable sequences of objects. In a list, you can store objects of any type. You can also mix objects of different types within the same list, although list elements often share the same type.

  4. Python's Assignment Operator: Write Robust Assignments

    While you can't add new values to a list by assignment, dictionaries do allow you to add new key-value pairs using the assignment operator. In the example below ... Whenever you complete an action in the following list, Python runs an implicit assignment for you: Define or call a function; Define or instantiate a class; Use the current ...

  5. Dictionaries in Python

    Python provides another composite data type called a dictionary, which is similar to a list in that it is a collection of objects.. Here's what you'll learn in this tutorial: You'll cover the basic characteristics of Python dictionaries and learn how to access and manage dictionary data. Once you have finished this tutorial, you should have a good sense of when a dictionary is the ...

  6. Python Dictionary (With Examples)

    Python Dictionary. Notes: Dictionary keys must be immutable, such as tuples, strings, integers, etc. We cannot use mutable (changeable) objects such as lists as keys. We can also create a dictionary using a Python built-in function dict(). To learn more, visit Python dict().

  7. 5 Best Ways to Initialize a List of Dictionaries in Python

    Method 3: Using the * Operator. Python's * operator can be used to repeat items in a list. To initialize a list of identical dictionaries without manually copying them, the * operator can be quite efficient; however, it creates shallow copies, so care should be taken when the dictionaries will be modified.

  8. Dictionaries in Python

    Adding items to the dictionary. We can add new items to the dictionary using the following two ways. Using key-value assignment: Using a simple assignment statement where value can be assigned directly to the new key. Using update() Method: In this method, the item passed inside the update() method will be inserted into the dictionary.The item can be another dictionary or any iterable like a ...

  9. Lists, Tuples and Dictionaries

    Chapter 3 - Lists, Tuples and Dictionaries. Python has several other important data types that you'll probably use every day. They are called lists, tuples and dictionaries. This chapter's aim is to get you acquainted with each of these data types. They are not particularly complicated, so I expect that you will find learning how to use ...

  10. Python Dictionaries: A Complete Overview • datagy

    Removing Items from Python Dictionaries. Similar to lists, Python provides a number of different ways to remove items from dictionaries. The first approach we'll take a look at is the del keyword. The keyword accepts a dictionary item and removes the item from the dictionary. Let's see how we can use the keyword to delete an item:

  11. Python Data Structures: Lists, Dictionaries, Sets, Tuples (2023)

    Data structure is a fundamental concept in programming, which is required for easily storing and retrieving data. Python has four main data structures split between mutable (lists, dictionaries, and sets) and immutable (tuples) types. Lists are useful to hold a heterogeneous collection of related objects.

  12. PDF Python Dictionaries

    Definite Loops and Dictionaries •Even though dictionaries are not stored in order, we can write a for loop that goes through all the entries in a dictionary - actually it goes through all of the keys in the dictionary and looks up the values >>> counts = { 'chuck' : 1 , 'fred' : 42, 'jan': 100} >>> for key in counts:... print key, counts[key]...

  13. Python dictionary assignment during list comprehension

    This can be done easily with a for loop, but I'm wondering if there's an idiomatic way to do it with a list comprehension. If it was an object instead of a dictionary I would just do: [setattr(k, v, False) for k, v in object if v is None] (or similar), but I'm not sure how to do it like that without using dict.__setitem__.

  14. 11.5. Multiple Assignment with Dictionaries

    11.5. Multiple Assignment with Dictionaries ¶. By combining items, tuple assignment, and for , you can make a nice code pattern for traversing the keys and values of a dictionary in a single loop: for key, val in list(d.items()): print(val, key) This loop has two iteration variables because items returns a list of tuples and key, val is a ...

  15. Python

    Sometimes, while working with Python dictionaries, we can have a problem in which we need to assign list elements as a new key in dictionary. This task can occur in web development domain. Lets discuss certain ways in which this task can be performed. Method #1 : Using zip() ...

  16. Dictionaries in Python

    Dictionaries in Python is a data structure, used to store values in key:value format. This makes it different from lists, tuples, and arrays as in a dictionary each key has an associated value. Note: As of Python version 3.7, dictionaries are ordered and can not contain duplicate keys. How to Create a Dictionary.

  17. Python Lists

    Lists are used to store multiple items in a single variable. Lists are one of 4 built-in data types in Python used to store collections of data, the other 3 are Tuple, Set, and Dictionary, all with different qualities and usage. Lists are created using square brackets:

  18. Creating Lists and Dictionaries

    00:00 Lists and dictionaries. Lists are powerful data structures in Python that often represent a series of related attributes. Similarly, dictionaries are used all over Python and are great for structuring information. 00:16 Sometimes when setting up these data structures, you end up performing the same operation several times. As a first example, calculate some basic descriptive statistics ...

  19. Python Operators

    Assignment Operators in Python. ... Merging and Updating Dictionary Operators in Python 3.9. Python 3.9 is still in development and scheduled to be released in October this year. On Feb 26, alpha 4 versions have been released by the development team. One of the latest features in Python 3.9 is the merge and update operators.

  20. Python Dictionaries

    Dictionary. Dictionaries are used to store data values in key:value pairs. A dictionary is a collection which is ordered*, changeable and do not allow duplicates. As of Python version 3.7, dictionaries are ordered. In Python 3.6 and earlier, dictionaries are unordered. Dictionaries are written with curly brackets, and have keys and values:

  21. Python for Data Science, AI & Development

    This module begins a journey into Python data structures by explaining the use of lists and tuples and how they are able to store collections of data in a single variable. Next learn about dictionaries and how they function by storing data in pairs of keys and values, and end with Python sets to learn how this type of collection can appear in ...

  22. Multiple assignments into a python dictionary

    Running the same test (on M1), I get different results: 934 µs ± 9.61 µs per loop; 1.3 ms ± 23.8 µs per loop; 744 µs ± 1.3 µs per loop; 1.02 ms ± 2.17 µs per loop; 816 µs ± 955 ns per loop; 693 µs ± 1.51 µs per loop; You can improve update's performance by instantiating a dict in advance; d1.update(dict(zip(keys, values))) has the same runtime as {**d1, **dict)(zip(keys, values ...

  23. Do assignments ever require locking?

    Core data types like dictionaries, lists, strings, etc should be safe from these kinds of critical failures. That's not to say there can't be other sorts of errors, and a simple x += 1 could well produce strange results, but at very very least, it won't result in a memory leak or a half-and-half pointer or anything like that.

  24. Lists and Tuples in Python

    Lists and tuples are arguably Python's most versatile, useful data types. You will find them in virtually every nontrivial Python program. Here's what you'll learn in this tutorial: You'll cover the important characteristics of lists and tuples. You'll learn how to define them and how to manipulate them.

  25. variable assignment

    Iterating over dictionaries using 'for' loops. 4670 What is the difference between @staticmethod and @classmethod in Python? 3876 How do I get the current time in Python? 3767 Convert bytes to a string in Python 3 ... python; variable-assignment; or ask your own question.