Python 通过读取具有默认值的文件创建字典

Python 通过读取具有默认值的文件创建字典,python,file,dictionary,collections,Python,File,Dictionary,Collections,我必须通过读取文件来创建字典 信息被分成几行 键位于括号之间,但并非所有键都是键。就在[日期]之后 在两个键之间是拆分为行的值,但并非所有行都是可选值 最终的结果应该是 d=[关键:[单位、高度、地点]] 某些键不具有所有值。然后,如果不存在单位、高度或场地,则应使用“”或0来满足该值 示例中的最终结果 param={AX1:['m/s',70.4,'site1'],H4:['''20.6,'site2'],V3:['m',0',]} 我知道如何从列表列表创建字典,但不知道如何设置默认值(字符串

我必须通过读取文件来创建字典

信息被分成几行

键位于括号之间,但并非所有键都是键。就在[日期]之后

在两个键之间是拆分为行的值,但并非所有行都是可选值

最终的结果应该是

d=[关键:[单位、高度、地点]]

某些键不具有所有值。然后,如果不存在单位、高度或场地,则应使用“”或0来满足该值

示例中的最终结果

param={AX1:['m/s',70.4,'site1'],H4:['''20.6,'site2'],V3:['m',0',]}

我知道如何从列表列表创建字典,但不知道如何设置默认值(字符串值为“”,数字值为0),以防缺少某些值

我试过使用集合中的defaultdict,但我对这个类还不是很熟悉,可能我没有使用它的所有可能性


感谢您提供的帮助

在确定密钥开始的点之后,这将为您提供有关如何解析文件其余部分的必要想法:

defaults = {'units':'', 'height':0, 'site':''}

with open(<file>) as f:
    <skip first section to date>

    param = {}
    d = {}
    tag = ""
    for line in f:
        if line[0] == '[':
            if tag:
                param[tag] = [d.get(k, defaults[k]) for k in ['units', 'height', 'site']]
            tag = line[1:-2]
            d = {}
            continue
        k,v = line.rstrip().split('=')
        d[k] = v
    else:
        param[tag] = [d.get(k, defaults[k]) for k in ['units', 'height', 'site']]
param
更新:我非常喜欢@MartinEvans使用configparser[py3](configparser[py2])的方法,但相信它可以更简单:

from configparser import ConfigParser
#from ConfigParser import ConfigParser  [py2]

with open(<file>) as f:
    <skip first section to date>

    config = ConfigParser()
    config['DEFAULT'] = {'units':'', 'height':0, 'site':''}
    config.read_file(f)
    # config.readfp(f)  [py2]
    for section in config.sections():
        param[section] = [config.get(section, k) for k in ['units', 'height', 'site']]
param

这可以使用Python实现,如下所示:

import ConfigParser
from itertools import dropwhile
import io

config = ConfigParser.ConfigParser({'unit' : '', 'units' : '', 'height' : 0, 'site' : ''})
skip = []

# Skip over lines until the first section is found
with open('input.txt', 'r') as f_input:
    for line in dropwhile(lambda x: not x.startswith('['), f_input):
        skip.append(line)

config.readfp(io.BytesIO('\n'.join(skip)))      

# Remove sections which are not required
for remove in ['Summary', 'System', 'date']:
    config.remove_section(remove)

param = {}
for section in config.sections():
    param[section] = [
        config.get(section, 'unit') + config.get(section, 'units'), 
        config.getfloat(section, 'height'),
        config.get(section, 'site')]

print param
为您提供输出:

{'AX1': ['m/s', 70.4, 'site1'], 'V3': ['m', 0.0, ''], 'H4': ['', 20.6, 'site2']}

此外,在找到第一个节之前,不会解析文件中的行,即以
[

开头的行。这看起来很不错,但是如果文件开头的行没有标题格式[],会怎么样。它会生成一个错误“MissingSectionHeaderError:文件不包含节标题”。如何使用config.read()从某一行读取?我已更新脚本,现在跳过任何非标准标题信息。它现在应该可以根据需要工作。
{'AX1': ['m/s', '70.4', 'site1'],
 'H4': ['', '20.6', 'site2'],
 'V3': ['m', 0, '']}
import ConfigParser
from itertools import dropwhile
import io

config = ConfigParser.ConfigParser({'unit' : '', 'units' : '', 'height' : 0, 'site' : ''})
skip = []

# Skip over lines until the first section is found
with open('input.txt', 'r') as f_input:
    for line in dropwhile(lambda x: not x.startswith('['), f_input):
        skip.append(line)

config.readfp(io.BytesIO('\n'.join(skip)))      

# Remove sections which are not required
for remove in ['Summary', 'System', 'date']:
    config.remove_section(remove)

param = {}
for section in config.sections():
    param[section] = [
        config.get(section, 'unit') + config.get(section, 'units'), 
        config.getfloat(section, 'height'),
        config.get(section, 'site')]

print param
{'AX1': ['m/s', 70.4, 'site1'], 'V3': ['m', 0.0, ''], 'H4': ['', 20.6, 'site2']}