简体   繁体   中英

Python: how to load json with dict containing range

my python code is about generating a sequence number from a dict keys, and my dict keys are defined with a range using cycle package in itertools module.

working example:

from itertools import cycle

e = {'Apple': cycle(range(1,999)),'Orange': cycle(range(1,999)),'Banana': cycle(range(1,999))}

def SequenceNum(f):
    return f'{next(e[f])}'.zfill(3)

X = SequenceNum('Apple')
print(X)

output

001 --> it keeps incrementing in the range specified above in dict `e`

Challenge:

My requirement is to convert this dict of e into a json file. So it will load keys and values by parsing json file.

cat test.json

{
    "DATA": {
        "Apple": "cycle(range(1,999))",
        "Orange": "cycle(range(1,999))",
        "Banana": "cycle(range(1,999))"
    }
}

(i had to put the dict values inside double quotes to avoid json file loading error.)

code

import json
from itertools import cycle

with open('test.json') as f:
    FromJson = json.load(f)
d = FromJson['DATA']
print(d)

def SequenceNum(f):
    return f'{next(d[f])}'.zfill(3)

X = SequenceNum('Apple')
i = 1
while i <= 10:
    print(i, SequenceNum('Apple'))
    i += 1

here new dict is d that loads json file and it will load the values in single quotes.

output

{'Apple': 'cycle(range(1,999))', 'Orange': 'cycle(range(1,999))', 'Banana': 'cycle(range(1,999))'} #THIS IS OUTPUT of 'd' after loading json file

Traceback (most recent call last):
  File "c:\Users\chandu\Documents\test.py", line 14, in <module>
    print(i, SequenceNum('Apple'))
  File "c:\Users\chandu\Documents\test.py", line 12, in SequenceNum
    return f'{next(d[f])}'.zfill(3)
TypeError: 'str' object is not an iterator

it is giving error because my dict values are not properly iterable by cycle itertools modules, since they are in quotes. i dont know if there is any other cause for this error.

please help to resolve this error,

Thanks in advance.

If you are sure what each value is, you can do eval with care:

def SequenceNum(f):
    return f'{next(eval(d[f]))}'.zfill(3)

Note this is very dangerous to use, because eval evaluates anything that is passed into it and can cause harm.


This also will always fetch first value from iterator as it is evaluated new everytime. To solve, you can:

def SequenceNum(f):
    return eval(d[f])

i = 1
seq_iter = SequenceNum('Apple')
while i <= 10:
    print(i, f'{next(seq_iter)}'.zfill(3))
    i += 1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM