python - Faster or better way than looping to find data? -


i have array of object of class person below, thisrate first set none:

class person(object):     def __init__(self, id, name):         self.id = id         self.name = name         self.thisrate= none 

i loaded around 21k person objects array, name not sorted.

then loaded array data in file has data thisrate, 13k of them, name not sorted well:

person_data = []  # read file row['name'] = 'peter' row['thisrate'] = '0.12334'  person_data.append(row) 

now these 2 sets of arrays, when name matched between them, assign thisrate person_data person.thisrate.

what doing loop this:

for person in persons:     data = none     try:         data = next(persondata persondata in person_data                         if persondata['name'] == person.name)     except stopiteration:         print("no rate person: {}".format(person.name))      if data:         person.thisrate = float( data['thisrate'] ) 

this loop

data = next(persondata persondata in person_data                 if persondata['name'] == person.name) 

is running fine , uses 21 seconds on machine python 2.7.13.

my question is, there faster or better way achieve same thing 2 arrays have?

yes. make dictionary name thisrate:

nd = {}  open(<whatever>) f:     reader = csv.dictreader(<whatever>):     row in reader:         nd[row['name']] = row['thisrate']  

now, use dictionary single pass on person list:

for person in persons:     thisrate = nd.get(person.name, none)     person.thisrate = thisrate     if thisrate none:         print("no rate person: {}".format(person.name)) 

dictionaries have .get method allows provide default value in case key not in dict. used none (which default default value) can use whatever want.

this linear-time solution. solution quadratic time, because doing:

for person in persons:     data in person_data:         if data['name'] == person.name:             person.thisrate = data['thisrate']             break     else:         print("no rate person: {}".format(person.name)) 

just in fashion obscures fundamentally nested for-loop inside of generator expression (not use-case generator expression, should have used for-loop begin with, don't have deal try-catch stopiteration


Comments