Reputation: 23
This function is meant to read a file into a dictionary, using the birdnames a keys and the weights as values. It is doing what I want but it isnt going through all the lines and im not sure why! Help a girl out? Here is my code:
def bird_weights(filename):
bird_dict = {}
f = open(filename, "r")
for line in f:
new_line = line.split(":")
bird_type = new_line[0].capitalize()
bird_weight = new_line[1].strip().split(' ')
bw_list = [float(i) for i in bird_weight]
bird_dict[bird_type] = bw_list
if bird_type in bird_dict:
bird_dict[bird_type].extend(bw_list)
else:
bird_dict[bird_type] = bw_list
return bird_dict
the .txt file is:
bluebird:78.3 89.3 77.0
TANAGER: 111.9 107.65
BlueBird: 69.9
bluebirD: 91.9
tanager: 108.0 110.0
and the code is meant to produce
{"Bluebird":[78.3, 89.3, 77.0, 69.9, 91.9],"Tanager": [111.9, 107.65, 108.0, 110.0]}
what i am getting is:
{"Bluebird":[91.9, 91.9], "Tanager": [108.0, 110.0, 108.0, 110.0] }
I am not sure why
Upvotes: 1
Views: 600
Reputation: 2126
So i know there are already a lot of solutions to this, but i'll just post one more :)
If you want to make your life a little bit easier and don't want to get confused by your code so easily, it sometimes helps to implement not the shortest but the most readable solution. If you're at this time only half understanding what your doing you will have a hard time half a year in the future when trying to change something on this code snippet.
So here is my fairly expressive solution and i think you'll be able to exactly understand what i did when you read through your bird_weights()
function:
class Bird(object):
def __init__(self, name, weights):
self.name = name
self.weights = weights
def __str__(self):
return self.name + ':' + str(self.weights)
def get_float_list(weights):
return [float(i.strip()) for i in weights.strip().split(' ')]
def print_birds(birdlist):
print '{'
for i in birdlist:
print str(i) + ','
print '}'
def bird_weights(f):
birdlist = []
for line in f:
name, weights = line.split(':')
birdy = Bird(name.capitalize(), get_float_list(weights))
birdlist.append(birdy)
print_birds(birdlist)
Happy flapping :)
EDIT: Sorry forgot to mention that you should pass this function now a opened file object (or a list of strings as i did for testing)
Upvotes: 0
Reputation: 103754
You cannot have multiple keys of the same value in a Python dict.
You can add an integer to each instance such as:
keys={}
birds={}
with open(file) as f:
for line in f:
k,_,v=line.partition(':')
k=k.capitalize()
v=map(float, v.split())
keys[k]=keys.setdefault(k, 0)+1
birds.setdefault('{} {}'.format(k, keys[k]), []).extend(v)
{'Tanager 1': [111.9, 107.65],
'Tanager 2': [108.0, 110.0],
'Bluebird 3': [91.9],
'Bluebird 2': [69.9],
'Bluebird 1': [78.3, 89.3, 77.0]}
Or, use a list of lists kind of structure:
birds={}
with open(file) as f:
for line in f:
k,_,v=line.partition(':')
k=k.capitalize()
v=map(float, v.split())
birds.setdefault(k, []).append(v)
{'Bluebird': [[78.3, 89.3, 77.0], [69.9], [91.9]],
'Tanager': [[111.9, 107.65], [108.0, 110.0]]}
Or, change append
to extend
for a flat list:
birds={}
with open(file) as f:
for line in f:
k,_,v=line.partition(':')
k=k.capitalize()
v=map(float, v.split())
birds.setdefault(k, []).extend(v)
{'Bluebird': [78.3, 89.3, 77.0, 69.9, 91.9], 'Tanager': [111.9, 107.65, 108.0, 110.0]}
Upvotes: 0
Reputation: 52103
def bird_weights(filename):
result = collections.defaultdict(list)
with open(filename, 'r') as f:
for line in f.readlines():
bird_name, values = line.strip().split(':')
# normalization
bird_name = bird_name.strip().capitalize()
values = map(lambda v: float(v.strip()), values.strip().split(' '))
result[bird_name].extend(values)
return result
Upvotes: 1
Reputation: 10135
It's because python's dictionary can't have duplicate keys. You are using 'capitalize' method, which made some bird's names identical.
Upvotes: 1
Reputation: 30943
Every time you see Bluebird
, you're overwriting what was already there. Try something like:
for line in f:
...
if bird_type in bird_dict:
bird_dict[bird_type].extend(bw_list)
else:
bird_dict[bird_type] = bw_list
to add to a pre-existing list for each bird_type
.
Upvotes: 0