0

With a list of dictionaries, in a json dataset (mydata.json) looking like this:

[
{"A": "123", "B": "456", "C": "789", "D": "1011"}, 
{"A": "1213", "B": "1415", "C": "1617", "D": "1819"},
... 
]

I am attempting to loop through each dictionary, and extract each key-value pair in the order in which it is stored.

I wish to retain the A, B, C, D sequence in that specific order per dictionary to be able to pass them into another piece of code that will process it further.

For simplicity, I'm testing it with printing each step through each iteration of the below nested for-loop.

Unfortunately it doesn't process the dictionaries in the way that I would need.

I need access to each key-value pair, per each loop, in that order, e.g. the first dictionary containing the key A, should be succeeded by the first B-C-D of that same dict.

Then the second dictionary should be processed, starting with A, then B-C-D, etc.

What I tried:

with open("mydata.json", "r") as read_file:
    md = json.load(read_file)

    for d in md:
        for k,v in d.items():
            if (k == "A"):
                print(k + ": " + v)
                continue
            if (k == "B"):
                print(k + ": " + v)
                continue
            if (k == "C"):
                print(k + ": " + v)
                continue
            if (k == "D"):
                print(k + ": " + v)
                continue
            else:
                continue

Desired output (strict sequential order):

A: 123    
B: 456
C: 789
D: 1011
A: 1213    
B: 1415
C: 1617
D: 1819

Actual output (scrambled order):

B: 456
D: 1011
A: 123    
C: 789
A: 1213
C: 1617
... etc. 

Any advice is greatly appreciated.

EDIT:

I have indeed marked my question as a duplicate, apologies for this! If I need to delete it altogether, to reduce clutter in SO, please leave a comment suggesting this. Thanks for the help!

sergei_22
  • 3
  • 3
  • what python version is this? note: python dictionaries were not ordered before python 3.6 (see here: https://stackoverflow.com/questions/39980323/are-dictionaries-ordered-in-python-3-6#39980548). – hiro protagonist Jul 09 '19 at 12:52
  • Dictionaries do not retain the order of their keys. – Scott Hunter Jul 09 '19 at 12:52
  • Try [OrderedDict](https://docs.python.org/2/library/collections.html#ordereddict-objects) – Piotr Kamoda Jul 09 '19 at 13:03
  • Welcome to Stack Overflow! Here is some guidance for deciding if the question should be deleted or left as a sign-post for others: https://meta.stackoverflow.com/a/300119/3975963 – Mike Bonnell Jul 09 '19 at 14:18

6 Answers6

0

Older versions of Python don't retain dictionary key order. From 3.7 onwards, it works well.

You could convert the items to a list and sort them before you use them in your loop if want - two iterations though, so less efficient.

You could use an OrderedDict from the collections module too - usage:

from collections import OrderedDict

ordered = OrderedDict()
# Now key order is remembered
Jack Bashford
  • 43,180
  • 11
  • 50
  • 79
0

You can sort the keys before iterate.

I removed the useless multiple if/continue statements and moved the for loop outside the with block because you should close the file as soon as you don't need it.

with open("mydata.json", "r") as read_file:
    md = json.load(read_file)

for d in md:
    for key in sorted(d.keys()):
        if key in ["A","B","C","D"]:
            print('{}: {}'.format(key, d[key]))
Corentin Limier
  • 4,946
  • 1
  • 13
  • 24
0

Below

from collections import OrderedDict
lst = [
  {"A": "123", "B": "456", "C": "789", "D": "1011"}, 
  {"A": "1213", "B": "1415", "C": "1617", "D": "1819"},
]
lst1 = []
for d in lst:
  tmp = sorted(d.keys())
  x = OrderedDict()
  for z in tmp:
    x[z] = d[z]
  lst1.append(x)
balderman
  • 22,927
  • 7
  • 34
  • 52
0

You can actually use the object_pairs_hook option of json.load to load in as an ordered dict in the first place.

from collections import OrderedDict
import json

js = '{"A": "123", "B": "456", "C": "789", "D": "1011"}'
md = json.loads(js, object_pairs_hook=OrderedDict)

When you provide the object_pairs_hook argument to json.load or json.loads, whenever the parser finds a json object, it passes that object as an ordered list of (already decoded) tuples to the function provided as object_pairs_hook. So in this case, loads passes the list [("A", "123"), ("B", "456"), ("C", "789"), ("D", "1011")] to OrderedDict.

Kyle Parsons
  • 1,475
  • 6
  • 14
0

try:

data = [
{"A": "123", "B": "456", "C": "789", "D": "1011"},
{"A": "1213", "B": "1415", "C": "1617", "D": "1819"}
]

for dict in data:
    for key, value in dict.items():
        print ("{}:{}".format(key,value))

output:

A:123
B:456
C:789
D:1011
A:1213
B:1415
C:1617
D:1819
ncica
  • 7,015
  • 1
  • 15
  • 37
-1

You could use Python 3.6+, then it will use the insertion order, though I am not sure if this works for JSON-parsing as well.

Otherwise, you could try first sorting the keys and loop over those.

I suppose using an OrderedDict would not be what you are looking for?

Lastly, perhaps you should try to avoid depending on the order in the further part of code (since that is under your control).

PascalVKooten
  • 20,643
  • 17
  • 103
  • 160