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
Post a Comment