您的代码是合理的,但这里有一个替代方案:
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)
产生
defaultdict(<type 'dict'>, {'A': {'A': 0, 'C': 6, 'B': 3}, 'C': {'A': 2, 'C': 0, 'B': 5}, 'B': {'A': 1, 'C': 7, 'B': 0}})
一些提示:
Use
with open(...) as f
...
instead of
f = open(...)
f.close()
because the file handle is closed for you when Python leaves the
with-block
. By using with
you'll never forget to close a filehandle, and even if an exception occurs, the filehandle will still be closed upon leaving the with-block
.
Generally, it is better to avoid f.readlines()
if you can. This
slurps the entire file into a list. That can be onerous on memory,
especially if the file is huge. Usually
with open(...) as f:
for line in f:
can be used instead.
If you make matrix
a collections.default(dict) then
matrix[field]
will be a dict
by default. So you can skip the
initialization:
for key in keys:
matrix[key] = {}
A defaultdict
is a subclass of dict
, so you can use it very much
as you would a dict
. If you don't like the way it prints or would
like to stop matrix
from automagically assigning an empty dict to
matrix[key]
for any key
, you can convert the defaultdict back to
a regular dict
with:
matrix = dict(matrix)
Avoid using numerical indices in for-loops
if you can.
for i, c in enumerate(chars[1:]):
Although this is de rigueur for most C-like languages, Python has a
better way: looping over the items themselves:
for col, val in zip(columns, vals):
This makes the code more readable, because it assigns a variable name
to the object you are actually interested in, not just an index which
you then have to compose into things like keys[i-1]
. It also helps
you avoid "off-by-one" errors which can occur when you have to adjust
the index by one, as is done in keys[i-1]
.
另一种可能是不使用嵌套字典,而是将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'])
顺便提一下,如果你安装了
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}}