2014-03-28 163 views
0

我有一個由多行組成的字符串,每行包含一個鍵和一個對象的2個屬性的2個值。我想將它們加載到字典中,並且字符串位於txt文件中。 我能夠儘量只去爲定義的函數:python - 用字符串填充字典

def load_a_string(self, thestring): 

這裏是字符串的樣子在txt文件(我想要的字符串開始於第四行):

noir 
False 
None 
((3, 0), 'blanc', 'pion') 
((5, 4), 'blanc', 'pion') 
((2, 1), 'noir', 'pion') 
((2, 5), 'noir', 'pion') 
((7, 2), 'blanc', 'pion') 
((1, 2), 'noir', 'pion') 
((6, 7), 'blanc', 'pion') 
((7, 6), 'blanc', 'pion') 
((6, 3), 'blanc', 'pion') 
((5, 6), 'blanc', 'pion') 
((5, 0), 'noir', 'pion') 
((0, 1), 'noir', 'pion') 
((3, 2), 'blanc', 'pion') 
((2, 3), 'noir', 'pion') 
((0, 7), 'noir', 'pion') 
((1, 0), 'noir', 'pion') 
((6, 5), 'blanc', 'pion') 
((2, 7), 'noir', 'pion') 
((7, 0), 'blanc', 'pion') 
((6, 1), 'blanc', 'pion') 
((7, 4), 'blanc', 'pion') 
((0, 5), 'noir', 'pion') 
((3, 4), 'noir', 'pion') 

從第4行開始是我想要轉換成字典的東西。每個數字元組是字典中的一個鍵,另外兩個是被稱爲片的類的實例(對象)的屬性,'blanc'或'noir'是屬性piece.color的值,'pion'是屬性piece.thetype(這是其他可能的值是'dame')。 基本上,如果我想手動填寫字典像上面是這樣的:

self.cases = {} 
self.cases[(3, 0)] = Piece("blanc", "pion") 
self.cases[(5, 4)] = Piece("blanc", "pion") 
self.cases[(2, 1)] = Piece("noir", "pion") 
... 

我正在做一個字符串作爲一個參數來填充字典的功能。這個函數是爲了在另一個函數中使用的,它會讀取像上面這樣的txt文件,並在文件中找到字符串,將其用作此函數的參數。所以我也想知道如何在上面的txt文件中找到字符串,所以我可以將它傳遞給這個函數。最後一部分將用於其他功能。有可能是一個更簡單的方法來做到這一點,但我真的需要這樣做,所以一切都融合在一起。

編輯:是的,這是真正的結構/格式,不幸的是我不能改變它。

+0

這個結構從哪裏來?操作 – njzk2

+0

似乎並不是很簡單,這就是爲什麼我在其他問題中詢問這些數據在何處。把一個python'repr'寫到一個文件中並不是一個很好的方法來重新獲取它。 – Eevee

+0

這真的是文件的結構,還是它是一個簡化的例子?如果它真的是結構,它會永遠是結構,還是未來會變得更加複雜? –

回答

2

如果這是真的格式,最簡單的方法是

rows = [x for x in open('file.ext', 'r')][3:] 

for x in rows: 
    key, color, thetype = eval(x) 
    dict[key] = Piece(color, thetype) 
+1

'eval'不是必需的,可能有害。改用'literal_eval'。 'literal_eval'只會解析Python數據結構 - 而不是代碼 – dawg

1

如果是由Python的生成文件,您可以訪問用來生成它的程序,或可誘發誰有權訪問的人,您應該考慮使用pickle模塊來存儲和保存Python數據的表示形式。

如果您不能使用更可靠的存儲機制和數據是否完全按照你的例子表示,那麼你可以爲每個行做這樣的事情:如果輸入的是安全

line = line.translate(None, '()') 
terms = line.split(',') 
self.cases[(terms[0], terms[1]) = Piece(terms[2], terms[3]) 
0

(它來自可信任方),您可以使用eval,它使用Python代碼獲取字符串,對其進行評估並返回結果。

例如:

from __future__ import print_function 
from collections import namedtuple 
from pprint import pprint 
import sys 

# Read the entire file to a list of lines 
with open('my_text.txt', 'r') as f: 
    lines = f.readlines() 

# Declare a Piece class, which is a named tuple (immutable) 
Piece = namedtuple('Piece', ['color', 'piece']) 

# The cases dictionary where we will write 
cases = {} 

# For lines 4 to last, counting them starting at 4... 
for num_line, line in enumerate(lines[3:], start=4): 
    try: 
     # Evaluate the line (will return a tuple) 
     a_tuple = eval(line) 

     # Separate the first element from the rest 
     key, params = a_tuple[0], a_tuple[1:] 

     # Write in the dictionary. *params is substituted with an argument for 
     # each element in the tuple params. 
     cases[key] = Piece(*params) 
    except: 
     # If something was wrong, print the line that failed in the text file 
     # and raise the exception to get the traceback and stop the program. 
     print("Failed to parse line %d: %s" % (num_line, line), file=sys.stderr) 
     raise 

# Pretty print the result 
pprint(cases) 
0

純Python字符串的解決方案:

txt="""\ 
noir 
False 
None 
((3, 0), 'blanc', 'pion') 
((5, 4), 'blanc', 'pion') 
((2, 1), 'noir', 'pion') 
((2, 5), 'noir', 'pion') 
((7, 2), 'blanc', 'pion') 
((1, 2), 'noir', 'pion') 
((6, 7), 'blanc', 'pion') 
((7, 6), 'blanc', 'pion') 
((6, 3), 'blanc', 'pion') 
((5, 6), 'blanc', 'pion') 
((5, 0), 'noir', 'pion') 
((0, 1), 'noir', 'pion') 
((3, 2), 'blanc', 'pion') 
((2, 3), 'noir', 'pion') 
((0, 7), 'noir', 'pion') 
((1, 0), 'noir', 'pion') 
((6, 5), 'blanc', 'pion') 
((2, 7), 'noir', 'pion') 
((7, 0), 'blanc', 'pion') 
((6, 1), 'blanc', 'pion') 
((7, 4), 'blanc', 'pion') 
((0, 5), 'noir', 'pion') 
((3, 4), 'noir', 'pion')""" 

d={} 
for line in txt.splitlines()[3:]: 
    data=line.strip()[1:-1].split(',') 
    d[line.partition(')')[0][1:]+')']=''.join(data[2:]) 

或者你可以使用literal_eval從AST:

from ast import literal_eval 

d={} 
for line in txt.splitlines()[3:]: 
    data=literal_eval(line) 
    d[data[0]]=data[1:] 

在兩種情況下:

>>> d 
{(3, 0): ('blanc', 'pion'), (3, 2): ('blanc', 'pion'), (2, 1): ('noir', 'pion'), (2, 5): ('noir', 'pion'), (7, 2): ('blanc', 'pion'), (1, 2): ('noir', 'pion'), (6, 7): ('blanc', 'pion'), (7, 6): ('blanc', 'pion'), (6, 3): ('blanc', 'pion'), (5, 6): ('blanc', 'pion'), (5, 0): ('noir', 'pion'), (2, 7): ('noir', 'pion'), (5, 4): ('blanc', 'pion'), (2, 3): ('noir', 'pion'), (0, 7): ('noir', 'pion'), (1, 0): ('noir', 'pion'), (6, 5): ('blanc', 'pion'), (0, 1): ('noir', 'pion'), (7, 0): ('blanc', 'pion'), (6, 1): ('blanc', 'pion'), (7, 4): ('blanc', 'pion'), (0, 5): ('noir', 'pion'), (3, 4): ('noir', 'pion')}'blanc' 'pion'", '(1, 0)': " 'noir' 'pion'", '(1, 2)': " 'noir' 'pion'", '(6, 1)': " 'blanc' 'pion'", '(7, 0)': " 'blanc' 'pion'", '(2, 5)': " 'noir' 'pion'", '(5, 6)': " 'blanc' 'pion'", '(7, 6)': " 'blanc' 'pion'", '(5, 0)': " 'noir' 'pion'", '(7, 4)': " 'blanc' 'pion'", '(7, 2)': " 'blanc' 'pion'"} 
0

這裏有一個簡單的方法使用正則表達式來提取這樣的數據應該是:

import re 

f = open('data','r') 
data = f.read() 
f.close() 

text = data.split('\n') 
dict = {} 
for line in text: 
    key = re.findall(r"\((\(\d\,\s\d\)),", line) 
    attr1 = re.findall(r",\s'(\w+)',", line) 
    attr2 = re.findall(r",\s'(\w+)'\)", line) 
    if len(key)>0: 
     dict[key[0]] = (attr1[0], attr2[0]) 
print dict 

這將涉及在文件中的行數據的任何情況,並且只捕獲想要的形式的數據,你不必擔心錯誤的格式化或空行,輸出將是:

{'(3, 0)': ('blanc', 'pion'), '(3, 4)': ('noir', 'pion'), '(2, 7)': ('noir', 'pion'), '(2, 1)': ('noir', 'pion'), '(3, 2)': ('blanc', 'pion'), '(2, 3)': ('noir', 'pion'), '(0, 1)': ('noir', 'pion'), '(0, 7)': ('noir', 'pion'), '(0, 5)': ('noir', 'pion'), '(6, 3)': ('blanc', 'pion'), '(6, 5)': ('blanc', 'pion'), '(5, 4)': ('blanc', 'pion'), '(6, 7)': ('blanc', 'pion'), '(1, 0)': ('noir', 'pion'), '(1, 2)': ('noir', 'pion'), '(6, 1)': ('blanc', 'pion'), '(7, 0)': ('blanc', 'pion'), '(2, 5)': ('noir', 'pion'), '(5, 6)': ('blanc', 'pion'), '(7, 6)': ('blanc', 'pion'), '(5, 0)': ('noir', 'pion'), '(7, 4)': ('blanc', 'pion'), '(7, 2)': ('blanc', 'pion')} 

希望這是一個幫助。