如何在数据嵌套严重时使用 python 获取信息
How to get information with python when data is heavily nested
我有一个文本文件,其中包含一些要挖掘的数据。
结构如下图
name (personA {
field1 : data1
field2 : data2
fieldN : dataN
subfield() {
fieldx1 : datax1
fieldxN : dataxN
}
}
name (personB {
field1 : data11
field2 : data12
fieldN : data1N
}
在某些人的记录中,子字段不存在,在这种情况下,输出应指定子字段未知。下面是我用来提取数据的代码
import re
data = dict()
with open('data.txt', 'r') as fin:
FLAG, FLAGP, FLAGS = False, False, False
for line in fin:
if FLAG:
if re.search('field1', line):
d1 = line.split()[2]
data['field1'] = d1
if re.search('fieldN', line):
dN = line.split()[2]
data['fieldN'] = dN
data['fieldxn'] = 'unknown'
FLAGP = True
if FLAGS:
if re.search('fieldxN', line):
dsN = line.split()[2]
data['fieldxn'] = dsN
if re.search('name\ \(', line):
pn = line.split()[1]
FLAG = True
data['name'] = pn
if re.search('subfield', line):
FLAGS = True
if len(data) == 4:
if FLAGP:
print data
FLAGP = False
FLAG = False
FLAGS = False
输出如下图
{'field1': 'data1', 'fieldN': 'dataN', 'name': '(personA', 'fieldxn': 'unknown'}
{'field1': 'data11', 'fieldN': 'data1N', 'name': '(personB', 'fieldxn': 'unknown'}
问题是我不知道在哪里打印数据,所以目前我使用下面的语句打印错误的数据
if len(data) == 4:
if FLAGP:
print data
FLAGP = False
FLAG = False
FLAGS = False
如果有人能提出任何正确检索数据的建议,我将不胜感激
我会采用不同的方法来解析,将子字段(和其他字段)存储在字典中。
data = open('data.txt', 'rt').read()
### Given a string containing lines of "fieldX : valueY"
### return a dictionary of values
def getFields(field_data):
fields = {}
if (field_data != None):
field_lines = field_data.strip().split("\n")
for pair in field_lines:
name, value = pair.split(":")
fields[name.strip()] = value.strip()
return fields
### Split the data by name
people_data = data.strip().split("name (")[1:]
### Loop though every person record
for person_data in people_data:
name, person_data = person_data.split(" {", 1) # split the name and the fields
# Split out the subfield data, if any
subfield_data = None
if (person_data.find("subfield()") > -1):
field_data, subfield_data = person_data.split("subfield() {", 1)
subfield_data = subfield_data.split("}")[0]
# Separate the fields into single lines of pairs
fields = getFields(field_data)
# and any subfields
subfields = getFields(subfield_data)
print("Person: "+str(name))
print("Fields: "+str(fields))
print("Sub_Fields:"+str(subfields))
这给了我:
Person: personA
Fields: {'field1': 'data1', 'field2': 'data2', 'fieldN': 'dataN'}
Sub_Fields:{'fieldx1': 'datax1', 'fieldxN': 'dataxN'}
Person: personB
Fields: {'field1': 'data1', 'field2': 'data2', 'fieldN': 'dataN'}
Sub_Fields:{}
因此您可以根据子字段是否为 None
或其他方式调整输出。这个想法是让你的数据输入到更灵活的结构中,而不是像你所做的那样 "brute-force" 解析。在上面,我经常使用 split()
来提供更灵活的方法,而不是依赖于查找确切的名称。显然这也取决于您的设计要求。
我有一个文本文件,其中包含一些要挖掘的数据。
结构如下图
name (personA {
field1 : data1
field2 : data2
fieldN : dataN
subfield() {
fieldx1 : datax1
fieldxN : dataxN
}
}
name (personB {
field1 : data11
field2 : data12
fieldN : data1N
}
在某些人的记录中,子字段不存在,在这种情况下,输出应指定子字段未知。下面是我用来提取数据的代码
import re
data = dict()
with open('data.txt', 'r') as fin:
FLAG, FLAGP, FLAGS = False, False, False
for line in fin:
if FLAG:
if re.search('field1', line):
d1 = line.split()[2]
data['field1'] = d1
if re.search('fieldN', line):
dN = line.split()[2]
data['fieldN'] = dN
data['fieldxn'] = 'unknown'
FLAGP = True
if FLAGS:
if re.search('fieldxN', line):
dsN = line.split()[2]
data['fieldxn'] = dsN
if re.search('name\ \(', line):
pn = line.split()[1]
FLAG = True
data['name'] = pn
if re.search('subfield', line):
FLAGS = True
if len(data) == 4:
if FLAGP:
print data
FLAGP = False
FLAG = False
FLAGS = False
输出如下图
{'field1': 'data1', 'fieldN': 'dataN', 'name': '(personA', 'fieldxn': 'unknown'}
{'field1': 'data11', 'fieldN': 'data1N', 'name': '(personB', 'fieldxn': 'unknown'}
问题是我不知道在哪里打印数据,所以目前我使用下面的语句打印错误的数据
if len(data) == 4:
if FLAGP:
print data
FLAGP = False
FLAG = False
FLAGS = False
如果有人能提出任何正确检索数据的建议,我将不胜感激
我会采用不同的方法来解析,将子字段(和其他字段)存储在字典中。
data = open('data.txt', 'rt').read()
### Given a string containing lines of "fieldX : valueY"
### return a dictionary of values
def getFields(field_data):
fields = {}
if (field_data != None):
field_lines = field_data.strip().split("\n")
for pair in field_lines:
name, value = pair.split(":")
fields[name.strip()] = value.strip()
return fields
### Split the data by name
people_data = data.strip().split("name (")[1:]
### Loop though every person record
for person_data in people_data:
name, person_data = person_data.split(" {", 1) # split the name and the fields
# Split out the subfield data, if any
subfield_data = None
if (person_data.find("subfield()") > -1):
field_data, subfield_data = person_data.split("subfield() {", 1)
subfield_data = subfield_data.split("}")[0]
# Separate the fields into single lines of pairs
fields = getFields(field_data)
# and any subfields
subfields = getFields(subfield_data)
print("Person: "+str(name))
print("Fields: "+str(fields))
print("Sub_Fields:"+str(subfields))
这给了我:
Person: personA
Fields: {'field1': 'data1', 'field2': 'data2', 'fieldN': 'dataN'}
Sub_Fields:{'fieldx1': 'datax1', 'fieldxN': 'dataxN'}
Person: personB
Fields: {'field1': 'data1', 'field2': 'data2', 'fieldN': 'dataN'}
Sub_Fields:{}
因此您可以根据子字段是否为 None
或其他方式调整输出。这个想法是让你的数据输入到更灵活的结构中,而不是像你所做的那样 "brute-force" 解析。在上面,我经常使用 split()
来提供更灵活的方法,而不是依赖于查找确切的名称。显然这也取决于您的设计要求。