2013-01-10 21 views
0

我已經寫了一些代碼來根據here描述的標準從存儲cnf的文件加載cnf。將連接範式的文件加載到列表中

該文件是:

c simple_v3_c2.cnf  // lines bigining by c are comments 
c 
p cnf 3 2    // the line bigining by p is the description of the pb 
1 -3 0     // folowing lines are formulation of the pb, with 0 as ending caractere 
2 3 -1 0 

我想將其加載到[[1,-3] [2,3,-1]]

我寫作品的代碼,但它對我來說似乎很醜陋。我會對它有一些反饋感興趣。 (我是python的新手)。

def loadCnfFile(fileName='example.cnf'): 
""" retourne une liste de listes d'entiers decrivants la forme normale conjonctive""" 
cnf=[] 
cnfFile = open(fileName, 'r') 
for line in cnfFile: 
    if line[0]!="c" and line[0]!="p": 
     l=line.split("0")[0].strip().split(" ") 
     m=[] 
     for k in l: 
      m.append(int(k)) 
     cnf.append(m) 
cnfFile.close() 
return cnf 

謝謝!

回答

1

使用list comprehension

In [66]: with open("example.cnf") as f: 
     print [map(int,line.split("0")[0].split()) for line in f if line and \ 
          not (line.startswith("c") or line.startswith("p"))] 
    ....:  
[[1, -3], [2, 3, -1]] 

或:

with open("example.cnf") as f: 
     x= lambda y,c:y.startswith(c) 
     print [map(int,line.split("0")[0].split()) for line in f if line and \ 
           not any(x(line,z) for z in ("c","p"))] 
    ....:  
[[1, -3], [2, 3, -1]] 
1

阿什維尼代碼是正確的,並呼籲有經驗的程序員(謝謝),但對於一個新來的Python(你彷彿是)也許一個簡單的for循環更容易理解:

result = [] 
with open("example.cnf") as f: 
    for line in f: 
     if not (line.startswith("c") or line.startswith("p")): 
      result.append([int(x) for x in line.rstrip("0").rstrip("0\n").split()]) 
+0

我不確定我喜歡'line.split(「0」)'。如果他們得到像'1 2 10 3'這樣的東西呢? – georg

+0

你說得對。我調整了我的樣本。現在使用rstrip(「0」),所以只有尾部零被刪除。 –

+0

或只是'rstrip(「0 \ n」)'。將調整我的樣本。 –

2

我想最好的飼料回到你的代碼將重寫它更「pythonic」的方式。例如:

def cnf_lines(path): 
    """Yields cnf lines as lists from the file.""" 

    with open(path) as fp: 
     for line in fp: 
      if not line.startswith(('c', 'p')): 
       items = map(int, line.split()) 
       yield items[:-1] 

要點:

  • PEP-8的一致性(在Python中沒有駝峯請)
  • 上下文管理器(with)的文件操作
  • 發電機(yield)代替積累名單

注:此代碼有意簡化並且不完全支持您鏈接的規格。

+0

感謝你的反饋,但是,也許你可以解釋我其他的東西:我不明白爲什麼所有的答案都使用'not line.startswith(「c」)'而不是'line [0]!=「c」'。使用啓動功能有沒有優勢,我不知道? (對我來說,第[0]行比第二種方法更明確 - 我從來沒有見過類似.startswith(),但我認爲這使得有經驗的程序員和noob =)有所不同。 – edelans

+0

@edelans:喜歡'startswith'有幾個原因,其中之一是它能夠一次檢查_multiple_可能的前綴。 – georg