2015-02-05 84 views
1

该函数旨在将文件读入字典中,使用birdnames a keys和权值作为值。它正在做我想要的,但它不是通过所有的线路,我不知道为什么!帮助一个女孩出去? 这里是我的代码:将文件读入字典python

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 

.txt文件是:

bluebird:78.3 89.3 77.0 
TANAGER: 111.9 107.65 
BlueBird: 69.9 
bluebirD: 91.9 
tanager: 108.0 110.0 

和代码是为了产生

{"Bluebird":[78.3, 89.3, 77.0, 69.9, 91.9],"Tanager": [111.9, 107.65, 108.0, 110.0]} 

什么,我得到的是:

{"Bluebird":[91.9, 91.9], "Tanager": [108.0, 110.0, 108.0, 110.0] } 

我不确定为什么

+0

@eumiro雅我修正了我的想法。它被更新。 –

回答

0

每当你看到Bluebird时,你都在覆盖已经存在的东西。尝试是这样的:

for line in f: 
    ... 
    if bird_type in bird_dict: 
     bird_dict[bird_type].extend(bw_list) 
    else: 
     bird_dict[bird_type] = bw_list 

添加到一个预先存在的列表中为每个bird_type

+0

什么是bw_list? –

+0

您的原始代码中的鸟重量列表。 –

+0

我更新了我的代码和结果。这是不正确的:/ –

1

这是因为python的字典不能有重复的键。你正在使用'大写'方法,这使得一些鸟的名字相同。

1
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 
+1

默认字典是非常优雅的东西。 –

+0

lower()是不需要的,如果你正在调用大写() – helloV

+0

谢谢@ helloV,我已经更新了我的答案。 – ozgur

0

在Python字典中不能有多个具有相同值的键。

可以整数添加到每个实例如:

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]} 

或者,使用列表这种结构的列表:

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]]} 

或者改变appendextend了平面列表:

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]} 
0

所以我知道已经有很多解决方案,但我只会发布一个:)

如果你想使你的生活更容易一点,不想让你的代码感到困惑所以很容易,它有时有助于实现不是最短但最可读的解决方案。如果你现在只有一半的时间了解你的行为,那么当你试图改变这段代码片段时,你会在将来半年遇到困难。

因此,这里是我的相当传神的解决方案,我想你就可以确切地了解什么,当你通过你的bird_weights()功能阅读我所做的:

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) 

扑快乐:)

编辑: 对不起忘了提及,你应该现在传递一个打开的文件对象(或一串字符串,如我为测试)此功能