Tôi có một tệp bao gồm hai cột, tức là,
1 a
2 b
3 c
Tôi muốn đọc tệp này vào từ điển sao cho cột 1 là khóa và cột 2 là giá trị, tức là
d = {1:'a', 2:'b', 3:'c'}
Tệp nhỏ, vì vậy hiệu quả không phải là một vấn đề.
Tôi có một tệp bao gồm hai cột, tức là,
1 a
2 b
3 c
Tôi muốn đọc tệp này vào từ điển sao cho cột 1 là khóa và cột 2 là giá trị, tức là
d = {1:'a', 2:'b', 3:'c'}
Tệp nhỏ, vì vậy hiệu quả không phải là một vấn đề.
Câu trả lời:
d = {}
with open("file.txt") as f:
for line in f:
(key, val) = line.split()
d[int(key)] = val
with
được sử dụng ở đây để xử lý việc dọn dẹp tệp. Khi bạn rời khỏi khối (chỉ bằng luồng thực thi thông thường hoặc theo một ngoại lệ), tệp sẽ tự động bị đóng. Bạn có thể đọc thêm về bối cảnh các nhà quản lý bằng Python ở đây: effbot.org/zone/python-with-statement.htm
for line in open("file.txt"):
làm sạch theo cách tương tự. Và nếu f là một giá trị cục bộ thì f
sẽ được giải phóng khi phạm vi bị mất. Trường hợp duy nhất mà câu lệnh này hữu ích là cho hàm dài (không tốt cho chất lượng) hoặc nếu bạn sử dụng một biến toàn cục.
for line in open('file.txt')
không không làm dọn dẹp cùng một cách. Không phải tất cả các triển khai Python đều giống nhau. with
đảm bảo tệp sẽ được đóng khi khối được thoát. Khi for
dòng hoàn tất, close
có thể được gọi. CPython
nó sẽ làm được, nhưng các phiên bản như IronPython
có bộ thu gom rác lười biếng.
Điều này sẽ để lại khóa dưới dạng một chuỗi:
with open('infile.txt') as f:
d = dict(x.rstrip().split(None, 1) for x in f)
dict([line.split() for line in f])
là đủ, imo.
dict([x.rstrip().split(None, 1) for x in f])
thay vì dict(x.rstrip().split(None, 1) for x in f)
. Đối với những người nghĩ cùng một điều, trước đây là một biểu thức trình tạo thay vì hiểu danh sách như được giải thích ở đây: python.org/dev/peps/pep-0289(PEP-289) . Học được điều gì đó mới!
Nếu phiên bản python của bạn là 2.7+, bạn cũng có thể sử dụng cách đọc chính tả như:
with open('infile.txt') as f:
{int(k): v for line in f for (k, v) in (line.strip().split(None, 1),)}
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)
partition
? và with
tuyên bố?
partition
nhanh hơn và được tạo cho chính xác mục đích này.
with
là một cách đơn giản để đảm bảo rằng nó là như vậy.
strip
, tôi sẽ nói.
Bằng cách hiểu từ điển
d = { line.split()[0] : line.split()[1] for line in open("file.txt") }
Hoặc bởi gấu trúc
import pandas as pd
d = pd.read_csv("file.txt", delimiter=" ", header = None).to_dict()[0]
IMHO một chút khó khăn hơn để sử dụng máy phát điện (có thể bạn cần 2.7+ cho việc này):
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()}
Điều này cũng sẽ lọc ra các dòng không bắt đầu bằng số nguyên hoặc không chứa chính xác hai mục
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)
re
? nghiêm túc?
split()
không hoạt động gần như im lặng nếu định dạng tệp không tốt.
Nếu bạn yêu thích một lớp lót, hãy thử:
d=eval('{'+re.sub('\'[\s]*?\'','\':\'',re.sub(r'([^'+input('SEP: ')+',]+)','\''+r'\1'+'\'',open(input('FILE: ')).read().rstrip('\n').replace('\n',',')))+'}')
Đầu vào FILE = Đường dẫn đến tệp, SEP = Ký tự phân tách Khóa-Giá trị
Không phải là cách làm thanh lịch hay hiệu quả nhất, nhưng vẫn khá thú vị :)
Đây là một tùy chọn khác ...
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:]
Hầu hết các phương pháp lưu trữ từ điển sử dụng JSON, Pickle hoặc đọc dòng. Với điều kiện bạn không chỉnh sửa từ điển bên ngoài Python, phương pháp đơn giản này sẽ đủ cho các từ điển phức tạp. Mặc dù Pickle sẽ tốt hơn cho các từ điển lớn hơn.
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