我有一个包含各个步骤的问题。
我正在解析一个看起来像这样的文件:
9
123
0 987
3 890 234 111
1 0 1 90 1 34 1 09 1 67
1 684321
2 352 69
1 1 1 243 1 198 1 678 1 11
2 098765
1 143
1 2 1 23 1 63 1 978 1 379
3 784658
1 43
1 3 1 546 1 789 1 12 1 098
我想在文件的每一行,字典的键(忽略第一个数字,而取第二个,因为它只表明应该是哪个键):
0 987
1 684321
2 098765
3 784658
下面这行,元素的值(也只忽略第一个数字,因为它只表示有多少个元素):
3 890 234 111
2 352 69
1 143
1 43
所以最后它必须看起来像这样:
d = {987 : [890, 234, 111], 684321 : [352, 69],
098765 : [143], 784658 : [43]}
到目前为止,我有这个:
findkeys = re.findall(r"\d\t(\d+)\n", line)
findelements = re.findall(r"\d\t(\d+)", line)
listss.append("".join(findelements))
d = {findkeys: listss}
正则表达式需要更多的例外,因为一个用于键,它给了我其他行的元素,我不希望它们成为键,但是也只有一个数字。就像在文件示例中一样,结果显示为数字43。
元素的正则表达式使我回到所有的行上。
我不知道使代码忽略我不需要信息的行是否更容易,但是我不知道该怎么做。
我希望它保持简单有可能。 谢谢!
答案 0 :(得分:1)
with open('filename.txt') as f:
lines = f.readlines()
lines = [x.strip() for x in lines]
lines = lines[2:]
keys = lines[::3]
values = lines[1::3]
输出行:
['0 987',
'3 890 234 111',
'1 0 1 90 1 34 1 09 1 67',
'1 684321',
'2 352 69',
'1 1 1 243 1 198 1 678 1 11',
'2 098765',
'1 143',
'1 2 1 23 1 63 1 978 1 379',
'3 784658',
'1 43',
'1 3 1 546 1 789 1 12 1 098']
输出键:
['0 987', '1 684321', '2 098765', '3 784658']
输出值:
['3 890 234 111', '2 352 69', '1 143', '1 43']
现在,您只需将其放在一起!遍历键和值。
答案 1 :(得分:1)
一旦列表中有行(lines变量),您就可以简单地使用re来隔离数字,并使用字典/列表理解来构建所需的数据结构。
根据示例数据,每第3行都是一个键,其值在下一行。这意味着您只需在列表中跨3。
findall()将为您提供每一行的数字列表(作为文本),您可以忽略带有简单下标的第一个数字。
import re
value = re.compile(r"(\d+)")
numbers = [ [int(v) for v in value.findall(line)] for line in lines]
intDict = { key[1]:values[1:] for key,values in zip(numbers[2::3],numbers[3::3]) }
您也可以使用split()来执行此操作,但是随后您必须排除将在拆分中创建多个空格的空条目:
numbers = [ [int(v) for v in line.split() if v != ""] for line in lines]
intDict = { key[1]:values[1:] for key,values in zip(numbers[2::3],numbers[3::3]) }
答案 2 :(得分:0)
您可以使用例如parsimonious
:
from parsimonious.nodes import NodeVisitor
from parsimonious.grammar import Grammar
data = """
9
123
0 987
3 890 234 111
1 0 1 90 1 34 1 09 1 67
1 684321
2 352 69
1 1 1 243 1 198 1 678 1 11
2 098765
1 143
1 2 1 23 1 63 1 978 1 379
3 784658
1 43
1 3 1 546 1 789 1 12 1 098
"""
grammar = Grammar(
r"""
data = (important / garbage)+
important = keyline newline valueline
garbage = ~".*" newline?
keyline = ws number ws number
valueline = (ws number)+
newline = ~"[\n\r]"
number = ~"\d+"
ws = ~"[ \t]+"
"""
)
tree = grammar.parse(data)
class DataVisitor(NodeVisitor):
output = {}
current = None
def generic_visit(self, node, visited_children):
return node.text or visited_children
def visit_keyline(self, node, children):
key = node.text.split()[-1]
self.current = key
def visit_valueline(self, node, children):
values = node.text.split()
self.output[self.current] = [int(x) for x in values[1:]]
dv = DataVisitor()
dv.visit(tree)
print(dv.output)
这产生
{'987': [890, 234, 111], '684321': [352, 69], '098765': [143], '784658': [43]}
这里的想法是每个“键”仅由两个数字组成,第二个是“即将成为”关键字。下一行是价值线。