2015-07-14 4 views
1

Я хочу, чтобы разобрать файл YAML, имеющий следующую структуру данных:"TypeError: индексы списка должны быть целыми, а не str": yaml.load_all?

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 

Я следующий код, но я с «TypeError: список индексов должны быть целыми, не StR» в строке 20:

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

Может предоставить полный отклик, пожалуйста. Вы можете изменить свой вопрос, чтобы добавить его. – SiHa

+0

Прочтите и следуйте рекомендациям [PEP-0008] (https://www.python.org/dev/peps/pep-0008/). –

ответ

0

Предполагаю, что вы используете PyYaml.

load_all предназначен для загрузки нескольких документов YAML в один файл и поэтому всегда возвращает список. У вас только один документ, который сопоставляется с Python dict, поэтому вы должны просто использовать load.

0

Ваш пример - это странный, если не недопустимый файл YAML, что делает его частью работы над тем, что происходит здесь. Причина, по которой это проблематично файл YAML является

LFSDetails: | 

линия, которая имеет другую выемку (т.е. является outdented) по сравнению с линиями до и после.

До LFSDetails файл YAML выглядит так, как будто он имеет отображение на верхнем уровне. Таким образом, основное решение может состоять в том, чтобы просто нажать LFSDetails с двумя пробелами, чтобы выровнять его с этим. Это приведет к пустой строке в качестве буквального блока скаляра (введен с | и вашим кодом, кажется, полагаться на YAML в виде текстового блока в YAML. Таким образом, это выглядит как отступы следующих все строк ниже LFSDetails правильно.

для сообщения об ошибке появится файл YAML должно начинаться с (индикатором последовательности) тиром отступом 3 пробела:.

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

дает эту ошибку (я раздел нерелевантные промежуточные элементы отображения) Это, однако, разбирает, но полностью сбрасывает что-либо после outdentation на 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: является первым элементом последовательности/списка и после этого пытается получить доступ к элементу списка с помощью строки (LFSDetails) получает вас Ошибка.

Вы должны поэтому сначала очистить свой YAML, чтобы исправить ошибку. Я также предлагаю включить start of document marker (---), даже если у вас есть только один документ в файле примера, так как вы используете 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']) 

который получает вас в качестве вывода:

<type 'dict'> 
Y 

¹ Это было сделано с помощью ruamel.yaml которого я являюсь автором. Это расширенная версия PyYAML, и результаты с использованием этого должны быть похожими.

Смежные вопросы