4

次の形式のテキスト テーブルを解析する必要があります。

-----------------------------------------
| Serial |     Name             | marks |
| Number |First | Middle | Last |       |
-----------------------------------------
| 1      | john |   s    |  doe |  56   |
| 2      | jim  |   d    |  bill|  60   |

テーブルを解析した後、出力は、データをリストとして含むネストされたディクショナリになります。

TableData = {'Serial Number':[1,2], 
             'Name': {'First':[john, jim]} 
                     {'Middle':[s, d]} 
                     {'Last':[doe, bill]}
             'marks': [56, 60]
            }

今のところ、区切り記号 (|) の位置を取得するロジックがあり、区切り記号の間のテキストを抽出できます。

posList = [[0,9,32,40],[0,9,16,25,32]]
nameList = [['Serial','Name','marks'],['Number ','First','Middle','Last','  ']]

しかし、これをネストされた辞書構造に変換するのは困難です。

4

1 に答える 1

4

データ構造がどうあるべきかわかっているなら、最初の 3 行を忘れて、残りの行からデータを抽出できませんか? たとえば、テーブルがテキスト ファイルにあると仮定するとtable_file

table_data = {'Serial Number':[],
              'Name':{'First': [],
                      'Middle': []
                      'Last': []},
              'Marks': []}

with open(table_file, 'r') as table:
    # skip first 3 rows
    for _ in range(3):
        table.next()

    for row in table:
        row = row.strip('\n').split('|')
        values = [r.strip() for r in row if r != '']
        assert len(values) == 5
        table_data['Serial Number'].append(int(values[0]))
        table_data['Name']['First'].append(values[1])
        table_data['Name']['Middle'].append(values[2])
        table_data['Name']['Last'].append(values[3])
        table_data['Marks'].append(values[4])

編集: table_data ディクショナリを作成するには、次の疑似コードを検討してください。公正な警告、私はこれをテストしましたが、あなたの例ではうまくいくようで、ヘッダーが2行あるものなら何でもうまくいくはずです。ただ、10分くらいで書いたので雑です。ただし、そこから改善して拡張することは問題ありません。pos_listこれは、 およびを抽出するためのコードがあることも前提としていますname_list

for itertools import tee, izip
def pairwise(iterable):
    a, b = tee(iterable)
    next(b, None)
    return izip(a, b)

def create_table_dict(pos_list, name_list):
    intervals = []
    for sub_list in pos_list:
        intervals.append(list(pairwise(sub_list)))

    items = []
    for interval, name in zip(intervals, name_list):
        items.append([ (i, n) for i, n in zip(interval, name) ])

    names = []
    for int1, name1 in items[0]:
        past_names = []
            for int2, name2 in items[1]:
        if int1[0] == int2[0]:
            if int1[1] == int2[1]:
                names.append(' '.join((name1, name2)).strip())
        elif int2[1] < int1[1]:
                past_names.append(name2)
        elif int1[0] < int2[0]:
            if int2[1] < int1[1]:
            past_names.append(name2)
            elif int1[1] == int2[1]:
            names.append('{0}:{1}'.format(name1, 
                                          ','.join(past_names + [name2])))

    table = {}
    for name in names:
        if ':' not in name:
            table[name] = []
        else:
            upper, nested = name.split(':')
            nested = nested.split(',')
            table[upper] = {}
            for n in nested:
                table[upper][n] = []

    print table
于 2013-06-26T23:37:48.827 に答える