Last updated: Apr 8, 2024
Reading time·5 min
The Python "ValueError: dictionary update sequence element #0 has length N; 2
is required" occurs when we use the dict.update()
method incorrectly.
To solve the error, pass another dictionary or an iterable of key-value pairs
to the dict.update()
method.
Here is an example of how the error occurs.
my_list = ['name'] my_dict = {'name': 'Alice'} # ⛔️ ValueError: dictionary update sequence element #0 has length 4; 2 is required my_dict.update(my_list)
We called the dict.update()
method with a one-dimensional list which caused
the error.
You can call the dict.update()
method with:
my_dict = {'name': 'Alice'} # ✅ Passing a dict to update() my_dict.update({'name': 'Bobby'}) print(my_dict) # {'name': 'Bobby'}
my_dict = {'name': 'Alice'} # ✅ Passing a list of key-value pairs to update() a_list = [('name', 'Bobby'), ('age', 30)] my_dict.update(a_list) print(my_dict) # {'name': 'Bobby', 'age': 30}
dict.upate()
method with a dictionaryThe dict.update()
method can be called with a dictionary or an iterable of
key/value pairs (e.g. a list of tuples containing 2 elements).
my_dict = {'name': 'Alice'} # ✅ Pass a dictionary to the update() method my_dict.update({'name': 'Bobby', 'age': 30}) print(my_dict) # 👉️ {'name': 'Bobby', 'age': 30}
The example above passes a dictionary argument to the update()
method.
dict.update()
The method can also be called with an iterable of key/value pairs.
my_dict = {'name': 'Alice', 'age': 29} my_list = [('name', 'Bob'), ('age', 30)] my_dict.update(my_list) print(my_dict) # 👉️ {'name': 'Bob', 'age': 30}
We passed a list of tuples to the dict.update()
method. Each tuple must
contain 2 elements - a key and a value.
zip()
function to create a dictionary from 2 iterablesIf you have 2 iterables (e.g. lists or tuples) of equal length and need to
create a dictionary, use the zip()
function.
my_keys = ['name', 'age'] my_values = ['Bobby', 29] my_dict = dict(zip(my_keys, my_values)) print(my_dict) # 👉️ {'name': 'Bobby', 'age': 29}
The zip() function iterates over several iterables in parallel and produces tuples with an item from each iterable.
The zip
function returns an iterator of tuples.
The error is also caused when we try to convert a bad value to a dictionary.
my_str = 'hello' # ⛔️ ValueError: dictionary update sequence element #0 has length 1; 2 is required my_dict = dict(my_str)
Here are all the different ways to create a dictionary.
a = dict(name='Alice', age=29) b = {'name': 'Alice', 'age': 29} c = dict(zip(['name', 'age'], ['Alice', 29])) d = dict([('name', 'Alice'), ('age', 29)]) e = dict({'name': 'Alice', 'age': 29}) f = dict({'name': 'Alice'}, age=29) print(a == b == c == d == e == f) # 👉️ True
All of the examples create the same dictionary - {'name': 'Alice', 'age': 29}
.
The dict.update() method updates the dictionary with the key-value pairs from the provided value.
The method overrides the dictionary's existing keys and returns None.
The dict.update()
method can either be called with another dictionary or an
iterable of key-value pairs (e.g. a list of tuples with 2 elements each).
The error is also caused if you try to convert the string representation of a dictionary to a dictionary.
from ast import literal_eval my_str = '{"id": 1, "name": "Bobby Hadz", "salary": 30}' # ⛔️ ValueError: dictionary update sequence element #0 has length 1; 2 is required print(dict(my_str))
One way to resolve the issue is to use the ast.literal_eval()
method.
from ast import literal_eval my_str = '{"id": 1, "name": "Bobby Hadz", "salary": 30}' my_dict = literal_eval(my_str) print(my_dict) # 👉️ {'id': 0, 'name': 'Bobby Hadz', 'salary': 30} print(type(my_dict)) # 👉️ <class 'dict'>
The ast.literal_eval method allows us to safely evaluate a string that contains a Python literal.
json.loads()
method insteadAlternatively, you can use the json.loads()
method.
import json my_str = '{"id": 1, "name": "Bobby Hadz", "salary": 30}' my_dict = json.loads(my_str) print(my_dict) # 👉️ {'id': 1, 'name': 'Bobby Hadz', 'salary': 30} print(type(my_dict)) # 👉️ <class 'dict'>
We used the json.loads()
method to parse the string representation of a
dictionary to a native dict
object.
json.loads()
method can only be used if you have a valid JSON string.For example, the keys and values have to be double-quoted. This wouldn't work if the keys or values are wrapped in single quotes.
The json.loads() method parses a JSON string into a native Python object.
PyYAML
moduleIf your string isn't valid JSON, you can use the PyYAML
module.
First, install the module by running the pip install pyyaml command.
pip install pyyaml pip3 install pyyaml
Now you can import the module and use it to parse the string into a native Python dictionary.
import yaml my_str = "{'id': 1, 'name': 'Bobby Hadz', 'salary': 30}" my_dict = yaml.full_load(my_str) print(my_dict) # 👉️ {'id': 1, 'name': 'Bobby Hadz', 'salary': 30} print(type(my_dict)) # 👉️ <class 'dict'>
yaml.full_load()
method takes a YAML document, parses it and produces the corresponding Python object.Note that using the full_load()
method with untrusted input is not
recommended.
If you're working with untrusted data, use the yaml.safe_load()
method
instead.
import yaml my_str = "{'id': 1, 'name': 'Bobby Hadz', 'salary': 30}" my_dict = yaml.safe_load(my_str) print(my_dict) # 👉️ {'id': 1, 'name': 'Bobby Hadz', 'salary': 30} print(type(my_dict)) # 👉️ <class 'dict'>
The yaml.safe_load()
method loads a subset of the YAML language. This is
recommended for loading untrusted input.
If you got the error when using Django,
make sure to specify the name
keyword argument in your urlpatterns
list.
from django.urls import include, path urlpatterns = [ path('', views.home, name='home'), path('index/', views.index, name='main-view'), path('bio/<username>/', views.bio, name='bio'), path('articles/<slug:title>/', views.article, name='article-detail'), path('articles/<slug:title>/<int:section>/', views.section, name='article-section'), path('blog/', include('blog.urls')), # ... ]
If you forget to set the name
keyword argument, the error occurs.
# ⛔️ causes error path('', views.home, 'home') # -------------------------------- # ✅ doesn't cause the error path('', views.home, name='home')
dict.update()
methodYou can also pass keyword arguments to the dict.update()
method.
my_dict = dict(name='Alice', age=29) my_dict.update(name='Bob', age=30) print(my_dict) # 👉️ {'name': 'Bob', 'age': 30}
The code sample calls the dict.update()
method with name
and age
keyword
arguments.
The new values override the existing values for the specified properties.
I've also written an article on how to add items to a dictionary in a loop.
You can learn more about the related topics by checking out the following tutorials: