2012-02-16 71 views
17

Tôi muốn tạo một từ điển từ tệp văn bản mà tôi có, nội dung ở định dạng 'từ điển'. Dưới đây là một ví dụ về những gì các tập tin chứa:Python: Tạo Từ điển từ Văn bản/Tệp có định dạng từ điển

{ 'hươu con': [1], 'sermersheim': [3], 'sonji': [2], 'Scheuring': [2]}

Chính xác điều này ngoại trừ nó chứa 125.000 mục nhập. Tôi có thể đọc trong file văn bản sử dụng read(), nhưng nó tạo ra một biến của văn bản đen của các tập tin ngay cả khi tôi khởi tạo biến với

dict = {}

+8

'ast.literal_eval' – JBernardo

+1

@JBernardo 1 như miễn là bạn có Python 2.6 hoặc mới hơn, đó là cách để đi. Mô-đun 'ast' được giới thiệu trong 2.5, nhưng không có các hàm trợ giúp (chẳng hạn như' literal_eval'). Những người đến trong 2,6. –

+0

@JBernardo, câu trả lời hay nhất – dzhioev

Trả lời

23

Bạn có thể sử dụng eval built-in. Ví dụ, điều này sẽ có tác dụng nếu mỗi mục từ điển là trên một dòng khác nhau:

dicts_from_file = [] 
with open('myfile.txt','r') as inf: 
    for line in inf: 
     dicts_from_file.append(eval(line))  
# dicts_from_file now contains the dictionaries created from the text file 

Ngoài ra, nếu các tập tin chỉ là một từ điển lớn (thậm chí trên nhiều dòng), bạn có thể làm điều này:

with open('myfile.txt','r') as inf: 
    dict_from_file = eval(inf.read()) 

Đây có lẽ là cách đơn giản nhất để thực hiện, nhưng không phải là cách an toàn nhất. Như những người khác được đề cập trong câu trả lời của họ, eval có một số rủi ro bảo mật vốn có. Cách thay thế, như đã đề cập bởi JBernardo, là sử dụng ast.literal_eval an toàn hơn nhiều so với eval vì nó sẽ chỉ đánh giá các chuỗi có chứa các chữ. Bạn chỉ có thể thay thế tất cả các cuộc gọi thành eval trong các ví dụ trên với ast.literal_eval sau khi nhập mô-đun ast.

Nếu bạn đang sử dụng Python 2.4, bạn sẽ không có mô-đun ast và bạn sẽ không có các tuyên bố with. Mã sẽ trông giống như sau:

inf = open('myfile.txt','r') 
dict_from_file = eval(inf.read()) 
inf.close() 

Đừng quên gọi inf.close(). Vẻ đẹp của tuyên bố with là chúng làm điều đó cho bạn, ngay cả khi khối mã trong câu lệnh with làm tăng ngoại lệ.

+0

Nếu nó chỉ là một bức tường o 'văn bản? Đó là nghĩa đen chỉ là một chuỗi rắn bắt đầu bằng {và kết thúc bằng}. – Jared

+0

Nó vẫn hoạt động nếu chỉ có một dòng. – DynamiteReed

+0

Nó sẽ hoạt động nếu chỉ có một dòng, mặc dù nó sẽ không hoạt động nếu từ điển được trải ra trên nhiều dòng. Tôi đã thêm mã bổ sung cho trường hợp đó. –

0

Điều này trông giống như json với tôi. Sử dụng mô-đun json nếu có.

Điều này có vẻ giống yaml đối với tôi. Sử dụng pyyaml module nếu có. (Theo gợi ý của @jcollado).

Bạn không thể sử dụng mô-đun json vì nó nghiêm ngặt về đầu vào của nó.

+3

Nó không phải là JSON: nó sử dụng dấu nháy đơn thay vì dấu ngoặc kép. –

+0

@NedBatchelder: Có. Tôi đã không nhận ra rằng mô-đun 'json' nghiêm ngặt về đầu vào của nó. – Marcin

1

Sử dụng chức năng eval.

Ví dụ,

dict = eval(open("yourfile.txt").read()) 
+0

+1 'eval' chắc chắn là điều đơn giản nhất cần làm. Nhận xét được thực hiện bởi @JBernardo về 'ast.literal_eval' là an toàn hơn mặc dù vì nó chỉ cho phép các chuỗi, số, tuples, danh sách, dicts, booleans và None. Chỉ cần một cái gì đó để xem xét. – istruble

1

Tôi rất không khuyến khích sử dụng eval. Nó có thể dẫn đến các vấn đề bảo mật nếu bạn không có toàn quyền kiểm soát tập tin đầu vào. Chỉ cần nhập từ điển của bạn và lưu chúng bằng cách sử dụng mô-đun json hoặc pickle.

+0

Tôi đồng ý rằng eval là rủi ro bảo mật khổng lồ nếu được sử dụng thường xuyên hoặc trong mã sản xuất, tôi giải thích câu hỏi ban đầu cần được giải quyết ing với một bit cô lập mã đến từ một nguồn đáng tin cậy và đã có trong một tập tin văn bản. Với tình huống như vậy, bạn không thể làm được gì nhiều. – DynamiteReed

+0

Nó nằm trong một tệp tĩnh từ một nguồn đáng tin cậy, có! – Jared

+0

Và tôi đã không có may mắn với các tập tin dưa. Tôi có cùng thông tin này trong một tệp .pickle, nhưng dường như không thể tải nó lại. Mã này đang được chạy trên một hệ thống bị hạn chế không có truy cập internet. – Jared

3

Sử dụng eval có thể gây nguy hiểm.Nếu json không hoạt động, sau đó tôi khuyên bạn nên sử dụng yaml mà dường như làm việc tốt với ví dụ đầu vào của bạn:

>>> import yaml 
>>> yaml.load("{'fawn': [1], 'sermersheim': [3], 'sonji': [2], 'scheuring': [2]}") 
{'fawn': [1], 'scheuring': [2], 'sermersheim': [3], 'sonji': [2]} 
+0

Ah, tôi muốn sử dụng điều này nhưng tôi không có mô-đun và hệ thống mã đang được chạy trên không có truy cập internet. Dù sao cũng cảm ơn bạn! – Jared

+0

Bạn có thể muốn cân nhắc cài đặt từ nguồn. Theo tài liệu, nó phải dễ dàng như: 'python setup.py install'. – jcollado

1

Nó không phải là một giải pháp sản xuất sẵn sàng và có thể không làm việc tốt với một tệp có kích thước của bạn, nhưng nếu bạn cần một cách đơn giản và có thể thêm vào trước quý vị nộp để

my_dict = {'fawn': [1], 'sermersheim': [3], 'sonji': [2], 'scheuring': [2]} 

sau đó bạn có thể đổi tên nó vào một file python và chỉ cần nhập

from my_file import my_dict 
Các vấn đề liên quan