我想解析具有以下数据结构的YAML文件:
Version: 1
TxnCode: MPT
MessageID: "FFH-18544-1388620740-795905"
Recommendations:
- {ReqSegFlightRef: [[1,2]],TotalPriceRef: 1,PriceInfoRef: 1}
- {ReqSegFlightRef: [[3,4,2]],TotalPriceRef: 2,PriceInfoRef: 2}
- {ReqSegFlightRef: [[5,4,2]],TotalPriceRef: 3,PriceInfoRef: 3}
Flights:
- {OpCarrier: SN,MktCarrier: SN,FlightNb: 2902,DptDate: "0109",DptTime: "09:30",ArrTime: "11:05",DptAirport: VIE,ArrAirport: BRU}
- {OpCarrier: SN,MktCarrier: SN,FlightNb: 243,DptDate: "0109",DptTime: "12:15",ArrTime: "17:00",DptAirport: BRU,ArrAirport: FNA}
- {OpCarrier: OS,MktCarrier: LH,FlightNb: 6325,DptDate: "0109",DptTime: "06:30",ArrTime: "07:35",DptAirport: VIE,ArrAirport: MUC}
Prices:
- {TotalPrice: 1574.14,BaseAmount: 1368.00,TotalTaxe: 206.14,TotalSurcharge: 0.00,TotalFee: 0.00}
- {TotalPrice: 1633.57,BaseAmount: 1368.00,TotalTaxe: 265.57,TotalSurcharge: 0.00,TotalFee: 0.00}
- {TotalPrice: 1636.57,BaseAmount: 1368.00,TotalTaxe: 268.57,TotalSurcharge: 0.00,TotalFee: 0.00}
LFSDetails: |
PriceInfos:
- {FaresRef: [1,2],Price: {Total: 1574.14},Amount: {Total: 1368.00},Taxes: {Total: 206.14},Surcharges: {Total: 0.00},Fees: {Total: 0.00}}
- {FaresRef: [3,4,2],Price: {Total: 1633.57},Amount: {Total: 1368.00},Taxes: {Total: 265.57},Surcharges: {Total: 0.00},Fees: {Total: 0.00}}
- {FaresRef: [3,4,2],Price: {Total: 1636.57},Amount: {Total: 1368.00},Taxes: {Total: 268.57},Surcharges: {Total: 0.00},Fees: {Total: 0.00}}
ListCabinRequested: []
FareInfo:
- {RBD: M,FareBasis: BFFOWAT,PTC: ADT,BreakPointId: N,Availability: 9,Cabin: W,FareType: OB}
- {RBD: B,FareBasis: BFFOWAT,PTC: ADT,BreakPointId: Y,Availability: 9,Cabin: W,FareType: OB}
- {RBD: B,FareBasis: BFFOWAT,PTC: ADT,BreakPointId: N,Availability: 9,Cabin: M,FareType: OB}
Currency: EUR
我有以下代码,但我在第20行中遇到“TypeError:list indices必须是整数,而不是str”:
def yaml_load_all(iStream,iCodeFilter=None):
for ayamldoc in yaml.load_all(iStream):
lfsWrapper = LFSWrapper(iCodeFilter)
lfsDetails = ayamldoc['LFSDetails'] #line 20
if lfsDetails is not None:
ayamldoc['LFSDetails'] = yaml.load(lfsDetails)
lfsWrapper.loadDict(ayamldoc)
if lfsWrapper.isValid():
yield lfsWrapper
(我稍后调用此方法,将iStream设置为sys.stdin以读取数据文件)。
我认为我遗漏了一些关于数据结构或yaml.load_all工作方式的基本内容。
我错过了什么?
答案 0 :(得分:0)
我认为你正在使用PyYaml。
load_all
用于在单个文件中加载多个YAML文档,因此始终返回一个列表。你只有一个文档,它映射到Python dict,所以你应该使用load
。
答案 1 :(得分:0)
你的例子是一个奇怪的,如果不是一个无效的YAML文件,这使得它有点猜测工作在这里发生了什么。
是一个有问题的YAML文件的原因LFSDetails: |
与之前和之后的行相比具有不同缩进(即缩进)的行。
直到LFSDetails
YAML文件看起来在顶层有一个映射。因此,初始解决方案可能只是将LFSDetails
推入两个空格以使其与之对齐。这将导致一个空字符串作为其文字块标量(与|
一起引入,并且您的代码似乎依赖于YAML作为YAML中的文本块。所以它看起来像{{1}之后的所有行后面的缩进是正确的。
要显示您的错误消息,您的YAML文件必须以短划线(序列指示符)缩进3个空格开始:
LFSDetails
给出了这个错误(我删除了不相关的中间映射条目)。然而,这会解析,但在 -
Version: 1
LFSDetails: |
PriceInfos:
- {FaresRef: [1,2],Price: {Total: 1574.14},Amount: {Total: 1368.00},Taxes: {Total: 206.14},Surcharges: {Total: 0.00},Fees: {Total: 0.00}}
¹:
LFSDetails
给你:
import ruamel.yaml as yaml
yaml_str = """\
-
Version: 1
LFSDetails: |
PriceInfos:
- {FaresRef: [1,2],Price: {Total: 1574.14},Amount: {Total: 1368.00},Taxes: {Total: 206.14},Surcharges: {Total: 0.00},Fees: {Total: 0.00}}
"""
for data in yaml.load_all(yaml_str):
print(data)
print data['LFSDetails']
由于破折号,以[{'Version': 1}]
Traceback (most recent call last):
File "try.py", line 54, in <module>
print data['LFSDetails']
TypeError: list indices must be integers, not str
开头的映射是序列/列表的第一个元素,然后尝试访问带有字符串(Version:
)的列表元素,会得到错误。< / p>
因此,您应首先清理您的YAML以使其正确。我还建议您包含start of document marker(LFSDetails
),即使您在示例文件中只有一个文档,因为您使用的是---
。并摆脱额外的缩进(即事情从行的第一列开始)。删除任何虚假序列后,开始破折号,得到类似的东西:
load_all()
将您视为输出:
import ruamel.yaml as yaml
yaml_str = """\
---
Version: 1
TxnCode: MPT
MessageID: "FFH-18544-1388620740-795905"
Recommendations:
- {ReqSegFlightRef: [[1,2]],TotalPriceRef: 1,PriceInfoRef: 1}
- {ReqSegFlightRef: [[3,4,2]],TotalPriceRef: 2,PriceInfoRef: 2}
- {ReqSegFlightRef: [[5,4,2]],TotalPriceRef: 3,PriceInfoRef: 3}
Flights:
- {OpCarrier: SN,MktCarrier: SN,FlightNb: 2902,DptDate: "0109",DptTime: "09:30",ArrTime: "11:05",DptAirport: VIE,ArrAirport: BRU}
- {OpCarrier: SN,MktCarrier: SN,FlightNb: 243,DptDate: "0109",DptTime: "12:15",ArrTime: "17:00",DptAirport: BRU,ArrAirport: FNA}
- {OpCarrier: OS,MktCarrier: LH,FlightNb: 6325,DptDate: "0109",DptTime: "06:30",ArrTime: "07:35",DptAirport: VIE,ArrAirport: MUC}
Prices:
- {TotalPrice: 1574.14,BaseAmount: 1368.00,TotalTaxe: 206.14,TotalSurcharge: 0.00,TotalFee: 0.00}
- {TotalPrice: 1633.57,BaseAmount: 1368.00,TotalTaxe: 265.57,TotalSurcharge: 0.00,TotalFee: 0.00}
- {TotalPrice: 1636.57,BaseAmount: 1368.00,TotalTaxe: 268.57,TotalSurcharge: 0.00,TotalFee: 0.00}
LFSDetails: |
PriceInfos:
- {FaresRef: [1,2],Price: {Total: 1574.14},Amount: {Total: 1368.00},Taxes: {Total: 206.14},Surcharges: {Total: 0.00},Fees: {Total: 0.00}}
- {FaresRef: [3,4,2],Price: {Total: 1633.57},Amount: {Total: 1368.00},Taxes: {Total: 265.57},Surcharges: {Total: 0.00},Fees: {Total: 0.00}}
- {FaresRef: [3,4,2],Price: {Total: 1636.57},Amount: {Total: 1368.00},Taxes: {Total: 268.57},Surcharges: {Total: 0.00},Fees: {Total: 0.00}}
ListCabinRequested: []
FareInfo:
- {RBD: M,FareBasis: BFFOWAT,PTC: ADT,BreakPointId: N,Availability: 9,Cabin: W,FareType: OB}
- {RBD: B,FareBasis: BFFOWAT,PTC: ADT,BreakPointId: Y,Availability: 9,Cabin: W,FareType: OB}
- {RBD: B,FareBasis: BFFOWAT,PTC: ADT,BreakPointId: N,Availability: 9,Cabin: M,FareType: OB}
Currency: EUR
"""
for data in yaml.load_all(yaml_str):
lfs_data = data['LFSDetails']
nested_data = yaml.load(lfs_data)
print(type(nested_data))
print(nested_data['FareInfo'][1]['BreakPointId'])
¹这是使用ruamel.yaml完成的,我是作者。它是PyYAML的增强版本,使用它的结果应该类似。