在python中将文本网格转换为嵌套字典

2024-04-25 05:41:58 发布

您现在位置:Python中文网/ 问答频道 /正文

想象一下文本文件中的网格如下:

  A  B  C
A 0  1  2
B 3  0  5
C 6  7  0

在python中将其转换为字典的最佳方法是什么,如下所示:

^{pr2}$

所以我可以通过以下方式访问单元格:

matrix['A']['B'] # 3

我目前确实有一些非常粗糙的代码(请不要对我太苛刻):

matrix = {}
f = open(filepath, 'r')
lines = f.readlines()
keys = lines[0].split()

for key in keys:
    matrix[key] = {}

for line in lines[1:]:
    chars = line.split()
    key_a = chars[0]
    for i, c in enumerate(chars[1:]):
        key_b = keys[i-1]
        matrix[key_a][key_b] = int(c)

print matrix

# Outputs {'A': {'A': 1, 'C': 0, 'B': 2}, 'C': {'A': 7, 'C': 6, 'B': 0}, 'B': {'A': 0, 'C': 3, 'B': 5}}

虽然这没有错,但我已经离开python很久了,有没有更好的方法呢?也许嵌套字典实际上不是最好的方法?在

更新

  1. 不幸的是,我需要用vanilla python来实现这一点,所以不可能使用外部库(相信我会喜欢的)
  2. 将我的示例代码表单伪代码更新为实际代码。羞愧地垂着头。在

Tags: 方法key代码in网格for字典line
1条回答
网友
1楼 · 发布于 2024-04-25 05:41:58

您的代码是合理的,但这里有一个替代方案:

import collections
with open('grid_file.txt', 'r') as f:
    columns = next(f).split()
    matrix = collections.defaultdict(dict)
    for line in f:
        items = line.split()
        row, vals = items[0], items[1:]
        for col, val in zip(columns, vals):
            matrix[col][row] = int(val)
print(matrix)

它产生了

^{pr2}$

一些提示:

  • 使用

    with open(...) as f
        ...
    

    而不是

    f = open(...)
    f.close()
    

    因为当Python离开时file handle is closed for youwith-block。通过使用with,您将永远不会忘记关闭一个filehandle,即使发生异常,在离开with-block时,filehandle仍将被关闭。

  • 一般来说,最好尽量避免{}。这个 将整个文件拖进一个列表中。这可能会让你的记忆变得沉重, 尤其是如果文件很大的话。通常

    with open(...) as f:
        for line in f:
    

    可以代替使用。

  • 如果你使matrixacollections.default(dict),那么 matrix[field]默认为dict。所以你可以跳过 初始化:

    for key in keys:
        matrix[key] = {}
    
  • defaultdictdict的一个子类,因此您可以非常频繁地使用它 就像你一样。如果你不喜欢它的印刷方式 想停止matrix自动将空dict分配给 matrix[key]对于任何key,可以将defaultdict转换回 一个正则的dict,具有:

    matrix = dict(matrix)
    
  • 如果可以,请避免在for-loops中使用数字索引。在

    for i, c in enumerate(chars[1:]):
    

    尽管对于大多数类似C的语言来说这是一个derigueur,但是Python有一个 更好的方法:循环项目本身:

    for col, val in zip(columns, vals):
    

    这使得代码更具可读性,因为它指定了一个变量名 你真正感兴趣的对象,而不仅仅是一个 然后你必须把它们组合成keys[i-1]。这也有帮助 您可以避免“关闭一个”错误,这可能发生在您必须调整 按一索引,如keys[i-1]中所做的那样。


另一种可能是不使用嵌套dict,而是使用2元组(列、行)作为键:

with open('grid_file.txt', 'r') as f:
    columns = next(f).split()
    matrix = {}
    for line in f:
        items = line.split()
        row, vals = items[0], items[1:]
        for col, val in zip(columns, vals):
            matrix[col, row] = int(val)
print(matrix)

收益率

{('B', 'C'): 7, ('A', 'A'): 0, ('B', 'B'): 0, ('B', 'A'): 1, ('C', 'A'): 2, ('C', 'B'): 5, ('C', 'C'): 0, ('A', 'B'): 3, ('A', 'C'): 6}

然后您可以访问矩阵中的(列,行),如下所示:

print(matrix['A','C'])
# 6

顺便说一下,如果您安装pandas

import pandas as pd
import io

text = '''\
A  B  C
A 0  1  2
B 3  0  5
C 6  7  0'''

df = pd.read_table(io.BytesIO(text), sep='\s+')
print(df.to_dict())

收益率

{'A': {'A': 0, 'B': 3, 'C': 6},
 'B': {'A': 1, 'B': 0, 'C': 7},
 'C': {'A': 2, 'B': 5, 'C': 0}}

相关问题 更多 >