1

I have a dict like :

data = {
        'key1': value1,
        'key2': value2
}

Now how do i append a key value list stored in a string like

str0 = "key3:val3, key4:val4"
or
str = "{key3:val3, key4:val4}"

into the above json dict?

print data.update(str)
print data.update(ast.literal_eval(str))

gives error.

(also tried with quotes to keys) raise ValueError('malformed string')

ValueError: malformed string
Victor
  • 427
  • 1
  • 6
  • 19
  • 1
    This basically boils down to answering the question: [Handling lazy JSON in Python](http://stackoverflow.com/q/4033633/364696). You've got non-JSON inputs (if you rendered them correctly, they're JS object literals, but JS object literals are a superset of JSON; JSON requires property names to be quoted); Python's `json` module can't handle that. Solve the parsing issue, the updating is trivial. – ShadowRanger Jan 05 '16 at 02:55
  • How is this question in any way related to JSON? – Chris Martin Jan 05 '16 at 05:22

5 Answers5

1

As these strings are not valid json strings and these can have different structures, you have to parse the strings. For parsing the strings you can use regular expression. If the pattern is good then it can handle different strings. As an example:

import re

pat = re.compile(r'(\w+):(\w+)')  # \w matches any alphanumeric character

str0 = "key3:val3, key4:val4"
str1 = "{key3:val3, key4:val4}"

print dict(re.findall(pat, str0))
print dict(re.findall(pat, str1))

This will give you output:

{'key3': 'val3', 'key4': 'val4'}
{'key3': 'val3', 'key4': 'val4'}

Also you can use dictionary's update method to update you data dictionary. like,

data.update(dict(re.findall(pat, str0)))
salmanwahed
  • 9,450
  • 7
  • 32
  • 55
0

str is not well-formed JSON string. If you can generate your JSON string in the format str = "{'key3':'val3', 'key4':'val4'}" and it should work fine.

>>> import ast
>>> data = {'key1': 'value1', 'key2': 'value2'}
>>> str = "{'key3':'val3', 'key4':'val4'}"
>>> data.update(ast.literal_eval(str))
>>> data
{'key3': 'val3', 'key2': 'value2', 'key1': 'value1', 'key4': 'val4'}

If you have to stick to the original format, you have to write your owner parser as pointed out in PyNEwbie's answer.

Community
  • 1
  • 1
Jimmy
  • 63
  • 2
  • 9
0
str0 = "key3:val3, key4:val4"
or
str = "{key3:val3, key4:val4}"

These aren't well formed JSON strings. "JSONDecodeError: Expecting property name enclosed in double quotes:" What did the JSON string look like when you enclosed the key names with double quotes? Remember you'll need to change the outer ones to single quotes

This snippet worked fine for me:

import json

data = {
        'key1': 5,
        'key2': 3
}

str = '{"key3":3, "key4":2}'

foo = json.loads(str)
data.update(foo)
print(data)

>>> {'key3': 3, 'key2': 3, 'key4': 2, 'key1': 5}
Cameron Mochrie
  • 129
  • 1
  • 8
0

Basically you need to apply string manipulations to the string to convert the string input into the form you need for your analysis

If your data is structured like

str0 = "key3:val3, key4:val4"

Then take this approach

for item in str0,split(','):
    key,value = item.split(':')
    data[key] = value

When your input string is in this format

str = "{key3:val3, key4:val4}"

Take this approach

str = str.replace("{","").replace("}","")
for item in str.split(","):
    key, value = item.split(':')
    data[key] = value
PyNEwbie
  • 4,882
  • 4
  • 38
  • 86
  • As a rule, if you can find a legitimate parser, you want to use that. Inventing your own is a great way to handle the format wrong in edge cases. For example, in this case, using the `demjson` module suggested [here](http://stackoverflow.com/a/10591575/364696) may be a safer solution. JS object literal notation (like csv and XML) is not something you want to roll your own parser for; there are just too many ways to get it wrong. – ShadowRanger Jan 05 '16 at 03:00
0
  1. data.update is not going to work as it will only accept dict as input
  2. ast.literal_eval(str) is not going to work as the str is not in the right form.

Try the following:

import json
import ast
data = {'key1': 'value1', 'key2':'value2'}
print json.dumps(data) #stdout: {"key2": "value2", "key1": "value1"}
data_after_ast = ast.literal_eval(json.dumps(data))
print type(data_after_ast) #stdout: <type 'dict'>

Thus, it is clear that your str0 or str format is wrong by missing quotes.

To fix it:

  • Option 1: you pre-processed the string and add quotes
  • Option 2: direct parse the original string

The following code will work for format str0 by using Option 2

 for s in str0.split(','):
     [key,value]=s.split(":")
     data.update({key:value})

Hope it answers your question.

White
  • 627
  • 4
  • 10