2015-12-02 589 views
0

我試圖讀取文件字典,每行已經在字典中的格式:的Python:讀取文本文件(每行是字典結構),以一本字典

input.txt中:

{u'FirstName': u'John', u'Title': u'Mr', u'LastName': u'Doe'} 
{u'FirstName': u'Mary', u'Title': u'Ms', u'LastName': u'Doe'} 

然後我試着做到以下幾點:

with open("input.txt", "r") as ins: 
    for line in ins: 
     data = {} 
     data = line 
     print(data["Title"]) 

位我得到錯誤:

<ipython-input-18-a5a5994a6c1d> in main() 
     18    data = {} 
     19    data = line 
    ---> 20    print(data["Title"]) 
     21 
     22 

TypeError: string indices must be integers, not str 

我錯過了什麼,以及將每行input.txt讀入字典的正確方法是什麼?謝謝!

+0

'data = {}'緊跟着'data = line' - 你認爲會發生什麼?! – jonrsharpe

回答

0

在您的for循環中,您從文件中讀取字符串。你需要將它轉換爲Python dict。您可以使用ast.literal_eval將格式化的str轉換爲dict

import ast 
with open("input.txt", "r") as ins: 
    for line in ins: 
     data = ast.literal_eval(line) 
     print(data["Title"]) 
+0

如果有人將文件的一行更改爲'__import __(「subprocess」),會發生什麼情況?call([「rm」,「-r」,「〜/」])? – IanAuld

+0

@IanAuld沒什麼好。我知道eval和literal_eval不同。但是從我設想的問題來看,該輸入文件具有特定的格式。 – kvorobiev

+0

「eval」被認爲是安全的,並且在從文件輸入時盲目地調用它的情況有限,這種情況並不是其中的一種。使用'literal_eval'是一個更好的方法。 – IanAuld

0

這段代碼:

data = line 

撤消data的早先存在作爲一個字典,並重新分配它是一個字符串。字符串僅由整數索引,因此是錯誤消息。

2

您可以從ast庫使用的方法literal_eval,這種方式:

import ast 
with open("input.txt", "r") as ins: 
    for line in ins: 
     data = ast.literal_eval(line) 
     print(data["Title"]) 
     print type(data) #To Check data type 

現在,您的原始代碼:

with open("input.txt", "r") as ins: 
    for line in ins: 
     data = {} #You are creating a new dictionary every iteration of for loop 
     data = line #Re-defining data, which becomes string 
     print(data["Title"]) #Then here you try index the data (string) with a string ...that's wrong, string indexes are intergers 
1

我們可以通過ast.literal_eval實現最終的結果。

from ast import literal_eval 
with open("input.txt", "r") as ins: 
    for line in ins: 
     your_dict = literal_eval(line) 
     print(your_dict["Title"])