如何将文件转换成字典?


Answers:


154
d = {}
with open("file.txt") as f:
    for line in f:
       (key, val) = line.split()
       d[int(key)] = val

1
您能解释一下with语句吗?
VGE

12
with用于处理文件清理。当您离开该块时(无论是通过常规执行流还是通过异常),该文件都会自动关闭。您可以在此处阅读有关Python上下文管理器的更多信息:effbot.org/zone/python-with-statement.htm
Vlad H

1
for line in open("file.txt"):以相同的方式进行清理。如果f是局部值,f则在失去作用域时将释放该值。该语句唯一有用的情况是长函数(质量不好)或使用全局变量。
VGE

1
@VGE,for line in open('file.txt')没有做清理工作方式相同。并非所有的Python实现都是相同的。 with保证退出该块时文件将关闭。当for线齐全,close 可以被调用。 CPython会的,但是像这样的版本IronPython具有懒惰的垃圾收集器。
Mark Tolonen

2
这里真的需要int吗?也许他希望数字是字符串?
GL2014 2014年

15

这会将密钥保留为字符串:

with open('infile.txt') as f:
  d = dict(x.rstrip().split(None, 1) for x in f)

2
一个简单dict([line.split() for line in f])的就够了,imo。
user225312 2011年

@sukhbir:如果您阅读问题,您会发现这不是op想要的。
SilentGhost

@SilentGhost:我读到OP希望键为整数,但是Ignacio的解决方案(以及我删除的方案)的键为字符串(如Ignacio自己所指出的)。
user225312 2011年

我很困惑为什么在传递dict参数时我们不需要[]。即dict([x.rstrip().split(None, 1) for x in f])代替dict(x.rstrip().split(None, 1) for x in f)。对于那些想法相同的人,前者是生成器表达式,而不是列表解释,如此处所述:python.org/dev/peps/pep-0289(PEP-289)。学到新东西!
peaxol

1
@peaxol:为了不创建中间列表,我们使用生成器表达式而不是列表推导。
伊格纳西奥·巴斯克斯

7

如果您的python版本是2.7+,则还可以使用dict理解,例如:

with open('infile.txt') as f:
  {int(k): v for line in f for (k, v) in (line.strip().split(None, 1),)}

5
def get_pair(line):
    key, sep, value = line.strip().partition(" ")
    return int(key), value

with open("file.txt") as fd:    
    d = dict(get_pair(line) for line in fd)

1
为什么不partition呢?和with声明?
SilentGhost

@SilentGhost:我不知道分区!但是为什么在这种情况下str.split更好呢?关于“ with”:也许您可以为我澄清一下:关闭文件描述符超出范围还不够吗?我想在例外情况下,文件main保持打开状态,我将其更改。
tokland 2011年

partition更快,并且正是为此目的而创建的。
SilentGhost

描述符是否关闭是实现的细节。with是确保它是一种简单的方法。
SilentGhost

strip我会说,这仍然需要。
SilentGhost

3

通过字典理解

d = { line.split()[0] : line.split()[1] for line in open("file.txt") }

或熊猫

import pandas as pd 
d = pd.read_csv("file.txt", delimiter=" ", header = None).to_dict()[0]

熊猫只进入第一列
Maulik Madhavi

1
@Samer Ayoub如果键和值都为一个字长,则上述解决方案(字典理解)将起作用。如果我的文本文件包含以下数据,我该如何以年份为关键并以获胜团队为价值。1903年波士顿美国人1904年没有世界大赛1905年纽约巨人队1906年芝加哥白袜队1907年芝加哥小熊队1908年芝加哥小熊队
迪(Ridhi)

1
@Ridhi抱歉,迟来的答复。您可以只在第一个空格上拆分 stackoverflow.com/questions/30636248/… 或使用正则表达式作为split()的参数
Samer Ayoub

@ SamerAyoub-谢谢。

1

恕我直言,使用生成器的Python代码要多一些(为此,您可能需要2.7+):

with open('infile.txt') as fd:
    pairs = (line.split(None) for line in fd)
    res   = {int(pair[0]):pair[1] for pair in pairs if len(pair) == 2 and pair[0].isdigit()}

这还将滤除不是以整数开头或不包含正好两个项目的行


0
import re

my_file = open('file.txt','r')
d = {}
for i in my_file:
  g = re.search(r'(\d+)\s+(.*)', i) # glob line containing an int and a string
  d[int(g.group(1))] = g.group(2)

9
re?认真吗?
SilentGhost

我认为这不是最好的方法。
多诺万

@Seafoid说:“文件很小,因此效率不是问题。” split()如果文件格式不是健全的,则几乎不能静默地工作。
VGE

0

如果您喜欢一种内胆,请尝试:

d=eval('{'+re.sub('\'[\s]*?\'','\':\'',re.sub(r'([^'+input('SEP: ')+',]+)','\''+r'\1'+'\'',open(input('FILE: ')).read().rstrip('\n').replace('\n',',')))+'}')

输入FILE =文件路径,SEP =键值分隔符

这不是最优雅或有效的方法,但是还是很有趣的:)


0

这是另一个选择

events = {}
for line in csv.reader(open(os.path.join(path, 'events.txt'), "rb")):
    if line[0][0] == "#":
        continue
    events[line[0]] = line[1] if len(line) == 2 else line[1:]

0

简单的选择

大多数用于存储字典的方法都使用JSON,Pickle或行读取。如果您不是在Python之外编辑字典,那么即使是复杂的字典,此简单方法也已足够。尽管对于较大的词典,Pickle会更好。

x = {1:'a', 2:'b', 3:'c'}
f = 'file.txt'
print(x, file=open(f,'w'))    # file.txt >>> {1:'a', 2:'b', 3:'c'}
y = eval(open(f,'r').read())
print(x==y)                   # >>> True
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.