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