Загрузить файл для конъюнктивной нормальной формы в список списков
Я написал некоторый код для загрузки 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
Спасибо!
3 ответа
Решение
С помощью 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]]
Я полагаю, что лучшим отзывом о вашем коде было бы переписать его более "питоническим" образом. Например:
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
) вместо накопления списков
Примечание: этот код намеренно упрощен и не полностью поддерживает спецификации, на которые вы ссылаетесь.
Код Ashwini верен и привлекателен для опытного программиста (спасибо), но для кого-то новичка в 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()])