2012-09-06 44 views
1

我試圖解析項目在一個文本文件,並將它們存儲到一個列表。數據看起來是這樣的:Python中,需要從文本文件幫助解析物品進入名單

[(0, 0, 0), (1, 0, 0), (2, 0, 0), (3, 0, 0), (4, 0, 0), (5, 0, 0), (6, 0, 0)] 
[(10, 3, 1), (11, 3, 1), (12, 3, 1), (13, 3, 1), (13, 4, 1)] 
[(10, 3, 5), (11, 3, 5), (12, 3, 5), (13, 3, 5), (13, 4, 5), (13, 5, 5), (13, 6, 5)] 
[(6, 13, 5), (7, 13, 5), (8, 13, 5), (8, 14, 5), (7, 14, 5), (6, 14, 5), (6, 14, 6)] 

我能夠剝離「[」和「]」,但也無法與其餘信息保存到列表,這樣的格式: (X,Y,Z) 。任何幫助?

def dataParser(fileName): 
    zoneList=[]; zone=[] 
    input=open(fileName,"r") 

    for line in input: 
     vals = line.strip("[") 
     newVals = vals.strip("]\n") 

     print newVals 
     v=newVals[0:9] 
     zone.append(v) 

    input.close() 
    return zone 

回答

6

在這種特殊情況下,您可以使用ast.literal_eval

>>> with open("list.txt") as fp: 
...  data = [ast.literal_eval(line) for line in fp if line.strip()] 
... 
>>> data 
[[(0, 0, 0), (1, 0, 0), (2, 0, 0), (3, 0, 0), (4, 0, 0), (5, 0, 0), (6, 0, 0)], [(10, 3, 1), (11, 3, 1), (12, 3, 1), (13, 3, 1), (13, 4, 1)], [(10, 3, 5), (11, 3, 5), (12, 3, 5), (13, 3, 5), (13, 4, 5), (13, 5, 5), (13, 6, 5)], [(6, 13, 5), (7, 13, 5), (8, 13, 5), (8, 14, 5), (7, 14, 5), (6, 14, 5), (6, 14, 6)]] 

這是eval的「安全」版本。這不是一般的,但正是出於這個原因。如果你生成這個輸入,你可能想尋找到一個不同的方式來保存數據(「系列化」),無論是使用pickle或類似的東西JSON - 有很多同時使用,你可以找到SO的例子,別處。

+0

爲什麼使用eval不安全? – user1518600

+0

如果您正在執行不信任的數據,那只是不安全的。如果一些惡作劇者將'__import __(「os」)。system(「ls -laR /」)這一行添加到你的數據文件中,那麼將會列出你所有的文件,而不是每個惡作劇者都願意離開它在那裏..我把「安全」放在引號中的原因是我認爲危險往往被誇大了日常使用,但這是一個少數意見。 – DSM

+0

hm ...有趣的一點。即使您提供的解決方案對我來說太過先進。儘管一行內容儘可能簡潔,而且工作正常,但對我而言仍然有點難以理解。我仍然不習慣使用不同的類,但只是基礎。不過謝謝你! – user1518600

2

有些人可能不喜歡使用eval()這裏,但你可以使用它在一行做到這一點:

In [20]: lis=eval("[(0, 0, 0), (1, 0, 0), (2, 0, 0), (3, 0, 0), (4, 0, 0), (5, 0, 0), (6, 0, 0)]") 
In [23]: lis 
Out[23]: [(0, 0, 0), (1, 0, 0), (2, 0, 0), (3, 0, 0), (4, 0, 0), (5, 0, 0), (6, 0, 0)] 

使用文本文件:

In [44]: with open('data.txt') as f: 
    ....:  lis=[eval(x.strip()) for x in f] 
    ....:  print lis 
    ....:  
    ....:  
[[(0, 0, 0), (1, 0, 0), (2, 0, 0), (3, 0, 0), (4, 0, 0), (5, 0, 0), (6, 0, 0)], [(10, 3, 1), (11, 3, 1), (12, 3, 1), (13, 3, 1), (13, 4, 1)], [(10, 3, 5), (11, 3, 5), (12, 3, 5), (13, 3, 5), (13, 4, 5), (13, 5, 5), (13, 6, 5)], [(6, 13, 5), (7, 13, 5), (8, 13, 5), (8, 14, 5), (7, 14, 5), (6, 14, 5), (6, 14, 6)]] 
0

以下是如果你得到來自任何來源的這些數據,你不能完全信任一個壞主意,但如果數據將永遠是這種格式(和僅包含數字的元素)是這樣的非常簡單:

collect = [] 
for line in input: 
    collect.append(eval(line)) 
3

你可以不用EVAL,使用字符串分割方法和構造元組:

>>> st = "[(0,0,0), (1,0,0)]" 
>>> splits = st.strip('[').strip(']\n').split(', ') 
>>> splits 
['(0,0,0)', '(1,0,0)'] 
>>> for split in splits: 
... trimmed = split.strip('(').strip(')') 
... tup = tuple(trimmed.split(',')) 
... print tup, type(tup) 
... 
('0', '0', '0') <type 'tuple'> 
('1', '0', '0') <type 'tuple'> 
>>> 

從那裏,它只是追加到列表中。

+0

不錯!對於像我這樣的初學者來說,這正是我需要了解如何使用基本實用程序。非常感謝。 – user1518600

+0

+1,但不應使用'str'作爲變量名稱,因爲這樣會破壞'str'類型。 – DSM

+0

修好了,謝謝。這是我的壞習慣之一。 –

0

其他的答案只是正常工作,是一個簡單的解決這個特定的問題。但是我假設如果你在處理字符串時遇到了問題,那麼在你下一次遇到這個問題時,一個簡單的eval()函數將不會幫助你。

作爲一般規則,你要當你與這樣的問題走近做的第一件事,是定義你的分隔符。

[(0, 0, 0), (1, 0, 0), (2, 0, 0), (3, 0, 0), (4, 0, 0), (5, 0, 0), (6, 0, 0)] 

在這裏你可以看到「),(」是團體和一個簡單的逗號(之間潛在的分隔符「」)是值之間的分隔符。接下來,你要看看你需要什麼如你所指出的那樣,括號(「[」「]」「)提供的信息很少,我們還可以看到,因爲我們正在處理數值,所有的間距給我們的信息很少,需要除去。此信息

大廈,我設置了dataParser函數返回你要找的值的方法:

fileName= "../ZoneFinding/outputData/zoneFinding_tofu_rs1000.txt" 

def dataParser(fileName): 
    with open(fileName,"r") as input 
     zoneLst = [] 
     for line in input: 
      #First remove white space and the bracket+parenthese combos on the end 
      line = line.replace(" ","").replace("[(","").replace(")]","") 

      #Now lets split line by "),(" to create a list of strings with the values 
      lineLst = line.split("),(") 

      # At this point lineLst = ["0,0,0" , "1,0,0", "2,0,0", ...] 
      #Lastly, we will split each number by a "," and add each to a list 
      zone = [group.split(",") for group in lineLst] 

      zoneLst.append(zone) 

     return zoneLst 

在上面的例子中,所有值都存儲爲字符串。您也可以用下面的代碼替換區域的 定義以將值存儲爲浮點數。

zone = [ [float(val) for val in group.split(",")] for group in lineLst]