2012-05-10 42 views
0

我想將數據保存在文本文件中,並從這些文件創建字典,稍後將傳遞給函數。Python:需要幫助從文本文件創建字典並拆分列表

這裏是我的代碼:

def lesson_dictionary(filename): 
    print "Reading file ", filename 
    with open(filename) as f: 
     mylist = f.read().strip().split() 
     dictionary = OrderedDict(zip(mylist[::2], mylist[1::2])) #keep keys/values in same order as declared in mylist 
     print dictionary 
    return dictionary 

隨着爲sample.txt包含用空格隔開,它工作正常的鍵/值對的兩列的樣本文件。例如,

AB

CD

EF

產生像這樣的列表:

OrderedDict([('a', 'b'), ('c', 'd'), ('e', 'f')]) 

,但如果我更改代碼和.txt文件的內容,它打破了。例如,如果包括sample2.txt:

A:B

C:d

Ê:F

和我的代碼是

def lesson_dictionary(filename): 
    print "Reading file ", filename 
    with open(filename) as f: 
     mylist = f.read().strip().split(':') #CHANGED: split string at colon! 
     dictionary = OrderedDict(zip(mylist[::2], mylist[1::2])) 
     print dictionary 
    return dictionary 

我得到以下輸出:

OrderedDict([('a', 'b \nc'), ('d\ne', 'f')]) 

發生了什麼?爲什麼strip()爲第一個.txt文件而不是第二個?預先感謝您的幫助。

回答

4

原始split()分裂上的空白,並\n被認爲是空白。通過更改爲split(':'),您已刪除行尾的分隔符,因此一行的結尾與下一行的開頭合併,並在中間帶有一個額外的換行符。我不認爲有一個簡單的方法來修復它,除了一次讀取一行文件。

編輯:一些代碼來演示。

dictionary = OrderedDict() 
with open(filename) as f: 
    for line in f: 
     key, value = line.split(':') 
     dictionary[key.strip()] = value.strip() 

以上原件的精神:

with open(filename) as f: 
    mylist = [line.strip().split(':') for line in f] 
    dictionary = OrderedDict(mylist) 

第二種形式具有不自動從周圍的話剝離空白的缺點。根據你的例子,你可能需要這個。

+0

我真的建議的替代標記表明「......除了一次讀取文件的一行。」讓文件對象分割線,例如f'中的行將更具可讀性。 – Leovt

+0

感謝您的意見,@Leovt。 – user1186742

+0

這工作完美!非常感謝你的解釋和示例代碼,馬克。 – user1186742

0

如果你自己創建輸入文件,我相信json會更適合這個問題。

您可以使用它像這樣:

import json 

#write the dictionary to a file 
outfile = open(filename, 'w') 
json.dump(someDictionary, outfile) 

#read the data back in 
with open(filename) as infile: 
    newDictionary = json.load(infile) 
0

你試過打印出的myList內容?

myList = ["a", "b c", "d e", "f"] 

,如果你想讓他們的行爲方式相同第一空格替換冒號:

myList = f.read().replace(":", "").split() 

或者,如果你希望他們分割成鍵值對,只是使用字符串的切片,甚至拉鍊和奇數元素一起:

s = f.read().split() 
myDict = dict(zip(s[::2], s[1::2])) 
2

split()沒有分隔符在空格上分裂,這是空行和換行符/空格。如果冒號爲split,則該算法不再適用,所以換行符會顯示在輸出中。嘗試:

dictionary = Ordereddict(l.strip().split(':') for l in f) 
+0

非常感謝@spinlok的解釋。您的示例代碼起作用並且非常有用。這也很簡單直接。與Mark的方式相反,在一條線上進行拍攝是否有優勢? – user1186742

+0

@ user1186742,這樣做使用一半的內存,因爲你不一次創建一個列表,你會得到一個發生器,一次爲OrderedDict提供一個項目。 –

0

如果你想你的代碼分隔中立,即a:ba-ba#b和這樣的。而不是常規split()使用re.split()

import re 
pattern = re.compile(r"[^\w]")  # non-w char 
with open(filename, "rt") as fr: 
    return OrderedDict(pattern.split(l.strip()) for l in fr)