python:将文本文件转换为字典

python:将文本文件转换为字典,python,dictionary,Python,Dictionary,我有一个文本文件名xrb.txt,它的前几行是这样的- 1 N.A. 9.10 9.66 2 N.A. 8.20 8.48 3 N.A. 8.70 8.11 4 6.34 4.60 4.39 5 6.07 <5.74 4.35 6 N.A. 5.10 4.42 7 2.92 3.20 2.05 8 <1.25 1.44 0.72 你的代码不起

我有一个文本文件名xrb.txt,它的前几行是这样的-

1   N.A.    9.10    9.66 
2   N.A.    8.20    8.48 
3   N.A.    8.70    8.11  
4   6.34    4.60    4.39 
5   6.07    <5.74   4.35 
6   N.A.    5.10    4.42 
7   2.92    3.20    2.05 
8   <1.25   1.44    0.72 

你的代码不起作用的唯一原因是一个愚蠢的打字错误:

xrbdic[parts[0]] = (pa[1], pa[2], pa[3])
这将在
零件上引发
名称错误
,因为没有这样的变量。把它改成
pa
,你就能得到你想要的字典了


同时,你也没有把事情搞得那么复杂。但是你能把事情简化一点吗?当然

首先,
line.split()

这包括尾随的换行符,所以你也不需要行宽条带

其次,您可以使用一个切片,而不是显式列出所有部分

当我们这样做的时候,您永远不会关闭文件,这对于任何事情都是一个坏主意,除了一个将立即退出的快速脏脚本。您可以使用
with
语句使其更简单

因此:

然后就很容易把整个事情变成一个听写理解:

with open('xrb.txt') as f:
    xrbdic = {pa[0]: pa[1:] for pa in map(str.split, f)}

你的代码不起作用的唯一原因是一个愚蠢的打字错误:

xrbdic[parts[0]] = (pa[1], pa[2], pa[3])
这将在
零件上引发
名称错误
,因为没有这样的变量。把它改成
pa
,你就能得到你想要的字典了


同时,你也没有把事情搞得那么复杂。但是你能把事情简化一点吗?当然

首先,
line.split()

这包括尾随的换行符,所以你也不需要行宽条带

其次,您可以使用一个切片,而不是显式列出所有部分

当我们这样做的时候,您永远不会关闭文件,这对于任何事情都是一个坏主意,除了一个将立即退出的快速脏脚本。您可以使用
with
语句使其更简单

因此:

然后就很容易把整个事情变成一个听写理解:

with open('xrb.txt') as f:
    xrbdic = {pa[0]: pa[1:] for pa in map(str.split, f)}

您需要将代码中的最后一行更改为以下内容

xrbdic[pa[0]=(pa[1],pa[2],pa[3])


您编写了部分,而实际上您应该编写pa。

您需要将代码中的最后一行更改为以下内容

xrbdic[pa[0]=(pa[1],pa[2],pa[3])


你写了部分,而事实上你应该写私人助理。

字典理解可能是更惯用的答案

with open('xrb.txt','r') as f:
    text = f.readlines()

###please ignore
#xrbdic = {p.split()[0]:(p.split()[1],p.split()[2],p.split()[3]) for p in raw_text}
##old ugly one-liner

rows = [line.split() for line in lines]
xrbdic = {row[0]:(row[1],row[2],row[3]) for row in rows}

词典理解可能是一个更惯用的答案

with open('xrb.txt','r') as f:
    text = f.readlines()

###please ignore
#xrbdic = {p.split()[0]:(p.split()[1],p.split()[2],p.split()[3]) for p in raw_text}
##old ugly one-liner

rows = [line.split() for line in lines]
xrbdic = {row[0]:(row[1],row[2],row[3]) for row in rows}

非常感谢您的详细帮助。。即使没有打字错误,我的方法与你建议的方法相比还是很混乱。。谢谢():(1.25AM没有时间上班,我可能应该睡觉-这真是一个非常愚蠢的打字)。潘奇:下午的时候我犯了同样的愚蠢错误。在别人的代码中发现它们总是比在自己的代码中更容易。非常感谢您提供的详细帮助。。即使没有打字错误,我的方法与你建议的方法相比还是很混乱。。谢谢():(1.25AM没有时间上班,我可能应该睡觉-这真是一个非常愚蠢的打字)。潘奇:下午的时候我犯了同样的愚蠢错误。在别人的代码中发现它们总是比在你自己的代码中发现它们更容易。(我不敢相信我会犯这样愚蠢的错误..谢谢你指出:):(我不敢相信我会犯这样愚蠢的错误..谢谢你指出:)对字符串反复调用
split
的词典理解肯定不是惯用的。这样违反DRY会使代码更难阅读,运行速度更慢,并且更容易出现难以发现和调试的愚蠢错误。此外,为什么您要将整个文件读入一个大字符串中,只是为了调用
splitlines
,而您本可以使用文件本身作为一个可编辑的行,就像OP已经在做的那样?这也使得代码速度变慢,可读性变差,没有什么好的理由。我本可以用
text=f.readlines()
来代替,但由于我后来执行的是完全相同的执行,因此似乎是多余的。我选择使用
f.read()
并允许文件关闭,因为我不需要再打开它了——我倾向于在对其数据进行操作时保持文件打开,一旦我读取了它,这是有害的。至于拆分字符串,在列表comp中有没有更快乐的方法?我尝试对原始文本中的行执行
{p[0]:(p[1],p[2],p[3]),对line.split()中的p执行splitlines()操作
但这种语法是错误的,原因我现在已经很清楚了……或者我想如果您迫切需要使用更多内存或减少缓存命中数,您可以使用listcomp而不是genexpr……下一个答案是,我一定要编写一个递归函数,读取整个文件,但每行只运行一次递归,最后返回一个listcomp并使用
list.extend
将concat扩展到输出中。不需要便宜——反正现代计算机的内存太多了!;)对字符串反复调用
split
的词典理解肯定不是惯用的。这样违反DRY会使代码更难阅读,运行速度更慢,并且更容易出现难以发现和调试的愚蠢错误。此外,为什么您要将整个文件读入一个大字符串中,只是为了调用
splitlines
,而您本可以使用文件本身作为一个可编辑的行,就像OP已经在做的那样?这也使得代码速度变慢,可读性变差,没有什么好的理由。我本可以用
text=f.readlines()
来代替,但由于我后来执行的是完全相同的执行,因此似乎是多余的。我选择使用
f.read()
并允许文件关闭,因为我不需要再打开它了——我倾向于让文件保持打开状态