Code Review Stack Exchange is a question and answer site for peer programmer code reviews. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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
share|improve this question
    
Who or what are ttl and abst? Is this code even having the desired functionality with those results of the if/elif? – I'll add comments tomorrow yesterday
    
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. – Rahul yesterday

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'])
share|improve this answer
    
Looks nicer now. – Rahul yesterday
    
for product_no, product in json_data.items(): will not work. I need to loop for data in product_data: not in json_data: – Rahul yesterday
    
@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. – jonrsharpe yesterday
    
product_names and json_data are not same dict/array. you mean for product in product_data, product_no in json_data:? – Rahul yesterday
    
@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. – jonrsharpe yesterday

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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