John Mckhay
John Mckhay

Reputation: 95

ValueError: dictionary update sequence element #0 has length 1; 2 is required Python Dictionary

I'm currently running into this error and I cannot find the issue. At first, I thought it was because in the transformed_data[2], there was only 1, but that doesn't seem to be the case.

ValueError: dictionary update sequence element #0 has length 1; 2 is required

My code:

print(transformed_data)
country =transformed_data[0]
continent = transformed_data[1]
transformed_data[2] = transformed_data[2].replace("''",'test')
print(dict(transformed_data[2])) # when I add dict it does the error.
print((transformed_data[2])) # without dict, no error.

shell without dict:

['Qatar', 'ASIA', '{2001: 41.215}', '{2001: 615000}']
{2001: 41.215}
['Cameroon', 'AFRICA', '{2001: 3.324}', '{2001: 16358000}']
{2001: 3.324}
['Democratic Republic of Congo', 'AFRICA', '{2006: 1.553}', '{2006: 56578000}']
{2006: 1.553}
['Bulgaria', 'EUROPE', '{2001: 48.923}', '{2001: 7931000}']
{2001: 48.923}
['Poland', 'EUROPE', '{2001: 306.696}', '{2001: 38489000}']
{2001: 306.696}
['Lesotho', 'AFRICA', "{1975: ''}", "{1975: '1161000'}"]
{1975: test}
['Albania', 'EUROPE', '{2002: 3.748}', '{2002: 3126000}']
{2002: 3.748}
['Colombia', 'SOUTH AMERICA', '{2001: 56.259}', '{2001: 39630000}']
{2001: 56.259}
['Pakistan', 'ASIA', '{2012: 166.33}', '{2012: 187280000}']
{2012: 166.33}

Shell with dict:

Exception raised:
Traceback (most recent call last):
  File "/Applications/Thonny.app/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/doctest.py", line 1330, in __run
    compileflags, 1), test.globs)
  File "<doctest __main__.get_bar_co2_pc_by_continent[1]>", line 1, in <module>
    get_bar_co2_pc_by_continent(d1, 2001)
  File "/Users/bob/Desktop/python class/assignment/final/plot_data.py", line 33, in get_bar_co2_pc_by_continent
    print(dict(transformed_data[2]))
ValueError: dictionary update sequence element #0 has length 1; 2 is required

Upvotes: 3

Views: 31993

Answers (1)

Tyler
Tyler

Reputation: 398

The reason for the error is that the syntax for dict() does not expect a string. You could use dict() in the following way:

dict([[2001, 41.215], [2002, 3.748]])

Where the outer list corresponds to the dictionary itself, and each inner list corresponds to a key-value pair. This may not work in your input data though, so I'll give some other tips as well.

EDIT: If you are not able to use modules at all like you say, and if you can make assumptions about the data input, then you can, of course, just split on ': ' and convert left side to an integer and right side to a float. Make sure to remove the outside curly braces with a splice `s[1:-1].

l = '{2001: 53.01}'[1:-1].split(': ')
d = dict([[int(l[0]), float(l[1])]])

For a more robust solution using standard library modules, read on. /EDIT

dict() is not capable of converting strings to dictionaries. Use the json module instead for doing that conversion.

Documentation for the json module: https://docs.python.org/3/library/json.html

Unfortunately, because you are using integers as the keys for the dictionaries, you will still have errors. The json module only supports valid json, meaning it only supports having string keys.
This is valid json: '{"2001": 41.215}'
This is not valid json: '{2001: 41.215}'

If you have control over the input text, then it would be best to modify the keys of those dictionaries to be strings by adding double quotes to each side, either manually, or if they are generated, then by modifying the script that does so.

Otherwise, you can employ some kind of regex substitution to automatically fix the data just before reading it:

import re
# Assumes that ALL of your keys have no decimal places, 
#   and that none of your values look like '2001:' 
new_text = re.sub(r'([1-9][0-9]*):', r'"\1":', text)

Keep in mind that whichever method you choose, when the json module creates your dictionaries, they will have string keys. If you absolutely must use integer keys, you can still convert the keys using some sort of loop over the dictionary items:

keys = d.keys()
for k in keys:
    d[int(k)] = d[k]
    del d[k]

Here is an example which assumes that you converted the keys into strings beforehand for all cases (replaces dict() with json.loads()):

import json

print(transformed_data)
country =transformed_data[0]
continent = transformed_data[1]
transformed_data[2] = transformed_data[2].replace("''",'test')
print(json.loads(transformed_data[2])) # Use json module instead.

Upvotes: 6

Related Questions