Как преобразовать файл в словарь?


95

У меня есть файл, состоящий из двух столбцов, т.е.

1 a 
2 b 
3 c

Я хочу прочитать этот файл в словаре, чтобы столбец 1 был ключом, а столбец 2 - значением, т. Е.

d = {1:'a', 2:'b', 3:'c'}

Файл небольшой, поэтому эффективность не является проблемой.

Ответы:


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

1
Не могли бы вы объяснить заявление с помощью?
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')ничего не делать Cleanup таким же образом. Не все реализации Python одинаковы. withгарантирует, что файл будет закрыт при выходе из блока. Когда forлиния будет заполнена, close можно будет позвонить. CPythonэто будет, но в таких версиях IronPythonесть ленивые сборщики мусора.
Марк Толонен 02

2
Здесь действительно нужен int? Возможно, он хотел, чтобы числа были строками?
GL2014 08

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]), имо.
user225312

@sukhbir: если вы прочтете вопрос, то увидите, что op не этого хочет.
SilentGhost

@SilentGhost: Я читал, что OP хочет, чтобы ключи были целыми числами, но решение Игнасио (как и тот, который я удалил) имеет ключи в виде строки (как указал сам Игнасио).
user225312

Я был сбит с толку, почему нам не нужен [] при передаче аргумента 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 07

1
@peaxol: мы используем выражение генератора вместо понимания списка, чтобы не создавать промежуточный список.
Игнасио Васкес-Абрамс,


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": может быть, вы можете прояснить это для меня: разве недостаточно выйти за рамки, чтобы дескриптор файла был закрыт? Я предполагаю, что в исключении основной файл останется открытым, я его изменю.
tokland

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]


1
@Samer Ayoub Приведенное выше решение (понимание словаря) работает, если и ключи, и значение состоят из одного слова. Если в моем текстовом файле есть следующие данные: как сделать год ключами и команду-победителя значениями? 1903 Бостон Американцы 1904 Нет Мировой серии 1905 Нью-Йорк Джайентс 1906 Чикаго Уайт Сокс 1907 Чикаго Кабс 1908 Чикаго Кабс
Ридхи

1
@Ridhi Извините за запоздалый ответ. Вы можете либо разделить на первое пространство только stackoverflow.com/questions/30636248/…, либо использовать регулярное выражение в качестве аргумента для split ()
Самер Аюб

@ SamerAyoub- Спасибо.
Ридхи

1

IMHO немного больше pythonic для использования генераторов (возможно, для этого вам понадобится 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',',')))+'}')

Входной ФАЙЛ = Путь к файлу, SEP = Символ-разделитель значений ключа

Не самый элегантный и эффективный способ сделать это, но тем не менее довольно интересный :)



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

0

У меня было требование взять значения из текстового файла и использовать их в качестве пары значений ключа. у меня есть содержимое в текстовом файле как ключ = значение, поэтому я использовал метод разделения с разделителем как "=" и написал ниже код

d = {}
file = open("filename.txt")
for x in file:
    f = x.split("=")
    d.update({f[0].strip(): f[1].strip()})

При использовании метода полосы все пробелы до или после разделителя "=" удаляются, и вы получаете ожидаемые данные в формате словаря.


Привет, добро пожаловать в Stack Overflow! Ваш подход отличается от других пользователей, но не могли бы вы отредактировать его, заменив на =`` ответить на вопрос?
Prunus Persica
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.