2
\$\begingroup\$

Is there any better way to do this?

import json

product_data = [x for x in open('product_strings.txt', 'r', encoding='utf-8').read().split(',')]
json_data = json.load(open('tedata.json', 'r', encoding='utf-8'))


for product_no in json_data:
    for product in product_data:
        if product.lower() in json_data[product_no]['name'].lower():
            print (product.lower(), json_data[product_no]['name'])
        elif product.lower() in json_data[product_no]['des'].lower():
            print (product.lower(), json_data[product_no]['name'])

tedata.json contains (6mb with ~1000 objects)

{
    "12345": {
        "owner": "BMW int",
        "doman": "20/01/2016",
        "des": "a beautiful BMW with improvements with respect to older version of bmw.",
        "dopur": "25/07/2016",
        "purchaser": "Mitsubishi, Japan",
        "name": "BMW-8"
    },
    "12346": {
        "owner": "audi",
        "doman": "20/01/2016",
        "des": "a beautiful skoda with improvements with respect to older version of skoda.",
        "dopur": "25/07/2016",
        "purchaser": "Mokoto, Japan",
        "name": "skoda-1"
    }
}

product_strings file contains (small with ~100 such string)

audi,bmw,jaguar

code for testing:

import json

tedata = """{
    "12345": {
        "owner": "BMW int",
        "doman": "20/01/2016",
        "des": "a beautiful BMW with improvements with respect to older version of bmw.",
        "dopur": "25/07/2016",
        "purchaser": "Mitsubishi, Japan",
        "name": "BMW-8"
    },
    "12346": {
        "owner": "audi",
        "doman": "20/01/2016",
        "des": "a beautiful skoda with improvements with respect to older version of skoda.",
        "dopur": "25/07/2016",
        "purchaser": "Mokoto, Japan",
        "name": "skoda-1"
    }
}"""

product_strings = "audi,bmw,jaguar"

product_data = [x for x in product_strings.split(',')]
json_data = json.loads(tedata)


for product_no in json_data:
    for product in product_data:
        if product.lower() in json_data[product_no]['name'].lower():
            print (product.lower(), json_data[product_no]['name'])
        elif product.lower() in json_data[product_no]['des'].lower():
            print (product.lower(), json_data[product_no]['name'])

##prints ===>bmw BMW-8
\$\endgroup\$
  • \$\begingroup\$ Who or what are ttl and abst? Is this code even having the desired functionality with those results of the if/elif? \$\endgroup\$ – I'll add comments tomorrow Aug 5 '16 at 8:07
  • \$\begingroup\$ Mistakes in converting working code to snippet. Idea is to check if the name is in the object name or description. Please see my working code. \$\endgroup\$ – Rahul Patel Aug 5 '16 at 8:22
4
\$\begingroup\$

Your identifiers could be altered to make things clearer. What you're calling product_data is just a list of names, so perhaps product_names would be better. Then it follows that product should become product_name, as for product_name in product_names: makes perfect sense. And you should only call things x where that's the convention of the domain (e.g. mathematics).


One obvious code simplification is that you can iterate over a dictionary's keys and values simultaneously:

for product_no, product in json_data.items():
    for product_name in product_names:
        ...

This way your comparisons lower down are neater:

if product_name.lower() in product['name'].lower():

Rather than product_name.lower() every time you compare to it, lowercase everything once:

product_names = [name for name in product_strings.lower().split(',')]
                                               # ^ e.g. here

In this case you don't need it at all, as product_strings is already lowercase!


You can do multiple comparisons in one (logical) line, too, reducing duplication:

if (product_name in product['name'].lower() 
        or product_name in product['des'].lower()):
    print (product, product_spec['name'])
\$\endgroup\$
  • \$\begingroup\$ Looks nicer now. \$\endgroup\$ – Rahul Patel Aug 5 '16 at 8:41
  • \$\begingroup\$ for product_no, product in json_data.items(): will not work. I need to loop for data in product_data: not in json_data: \$\endgroup\$ – Rahul Patel Aug 5 '16 at 8:46
  • \$\begingroup\$ @Rahul ...so? You can still loop over product_data (now product_names) within that loop, just as you currently do inside for product_no in json_data:. It will work just fine; you loop over both. \$\endgroup\$ – jonrsharpe Aug 5 '16 at 8:47
  • \$\begingroup\$ product_names and json_data are not same dict/array. you mean for product in product_data, product_no in json_data:? \$\endgroup\$ – Rahul Patel Aug 5 '16 at 8:52
  • \$\begingroup\$ @Rahul what? I know they're different, but your code iterates over both of them. You're welcome to try what you think I mean, but it won't work. So try what I actually wrote instead. I will update to show how it relates to the other line; note that I have renamed things per the opening paragraph. \$\endgroup\$ – jonrsharpe Aug 5 '16 at 8:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.