0

I have a variable that can look something like this:

('[{"path": ["$.parent_field.field_1"], "category": "A"}, {"path": ["$.field_2"], "category": "B"}, {"path": ["$.null_path"], "category": "C"}]',)

Essentially I'm looking for the best way to 'cycle through' the variable

What I want to end up with is something like:

parent_field.field_1 and field_2

So I'm essentially looking to extract the path fields (after the $.) unless it is null_path

I've tried (where p is equal to the variable):

for i in p:
   print(i)

but that is giving me i as:

[{"path": ["$.parent_field.field_1"], "category": "A"}, {"path": ["$.field_2"], "category": "B"}, {"path": ["$.null_path"], "category": "C"}]

And then I am unable to cycle through i as hoped

nimgwfc
  • 936
  • 3
  • 19
  • Is that really what your variable looks like? It is a *string representation* of a *python tuple* of a *python list* of *python dict*s which seems weird. How did you get it? – Andrew Jaffe Aug 03 '20 at 10:25
  • I'm using psycopg2 and it is returned from a select statement on the DB, so psycopg2 puts the outer bracket on it I think – nimgwfc Aug 03 '20 at 10:28
  • It's not the outer brackets that are the real problem, it's the outer quotes. What you want is the actual list of dicts: `[{...}, {...}]`, not its string version. You can get that via `eval` but I suspect there's a more direct way. (I don't know anything about psycopg2.) – Andrew Jaffe Aug 03 '20 at 10:33
  • 1
    The string value is valid json. So just do `json.loads(i)`. – ekhumoro Aug 03 '20 at 10:35
  • Ah, so it's `json` not a `dict`. That makes sense. Thx, @ekhumoro. – Andrew Jaffe Aug 03 '20 at 10:36

2 Answers2

1

First, you need to convert the json string to a dict, and then find the appropriate entries:

import json
result = json.loads(p[0])  ### it's a single-element tuple
paths = []
for pathdict in result:
    paths.append(pathdict['path'][0]) ## single-element lists

print(path)

which gives

['$.parent_field.field_1', '$.field_2', '$.null_path']

If you actually want more than just the 'path' element, you can loop over the pathdicts in various ways.

Andrew Jaffe
  • 23,727
  • 2
  • 45
  • 55
0

Here is one way to do it in a while loop and replacing the old string at each iteration:

s = '[{"path": ["$.parent_field.field_1"], "category": "A"}, {"path": ["$.field_2"], "category": "B"}, {"path": ["$.null_path"], "category": "C"}]'

while True:
    start = s.find('["$.')+4
    end = s.find('"]')
    if start>0 and end>0:
        print(s[start:end])
        s = s[end+1:]
    else:
        break

Giving you the following print out:

parent_field.field_1
field_2
null_path

----- Edit ------

A better way might be to do it like this, if the variable s is structured as follows:

s = ('[{"path": ["$.parent_field.field_1"], "category": "A"}', '{"path": ["$.field_2"], "category": "B"}', '{"path": ["$.null_path"], "category": "C"}]')

for sub_s in s:
    start = sub_s.find('["$.')+4
    end = sub_s.find('"]')
    if start>0 and end>0:
        print(sub_s[start:end])

Giving the exact same printout

JakobVinkas
  • 803
  • 3
  • 14