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
asked Aug 5, 2016 at 7:47
\$\endgroup\$
2
  • \$\begingroup\$ Who or what are ttl and abst? Is this code even having the desired functionality with those results of the if/elif? \$\endgroup\$ Commented Aug 5, 2016 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\$ Commented Aug 5, 2016 at 8:22

1 Answer 1

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'])
answered Aug 5, 2016 at 8:38
\$\endgroup\$
6
  • \$\begingroup\$ Looks nicer now. \$\endgroup\$ Commented Aug 5, 2016 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\$ Commented Aug 5, 2016 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\$ Commented Aug 5, 2016 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\$ Commented Aug 5, 2016 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\$ Commented Aug 5, 2016 at 8:53

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.