以IANA的格式为例:http://www.iana.org/assignments/language-subtag-registry
%%
Type: language
Subtag: aa
Description: Afar
Added: 2005-10-16
%%
Type: language
Subtag: ab
Description: Abkhazian
Added: 2005-10-16
Suppress-Script: Cyrl
%%
Type: language
Subtag: ae
Description: Avestan
Added: 2005-10-16
%%
说我打开文件:
import urllib
f = urllib.urlopen("http://www.iana.org/assignments/language-subtag-registry")
all=f.read()
通常你会这样做
lan=all.split("%%")
迭代lan和split("\n")
然后迭代结果并拆分(“:”),有没有一种方法可以在一个批处理的python中没有迭代,输出仍然是这样的:
[[["Type","language"],["Subtag", "ae"],...]...]
?
答案 0 :(得分:3)
如果在每次拆分后到达的元素在语义上有所不同,我认为在单次传递中尝试执行此操作没有任何意义。
你可以先用“:”分割 - 这会让你获得精细的数据 - 但如果你不知道这些数据属于什么,那会有什么好处呢?
那就是说,你可以将所有的分离水平放在发电机内,然后让它产生 带有数据的字典对象,可以用于消费:
def iana_parse(data):
for record in data.split("%%\n"):
# skip empty records at file endings:
if not record.strip():
continue
rec_data = {}
for line in record.split("\n"):
key, value = line.split(":")
rec_data[key.strip()] = value.strip()
yield rec_data
根据您在评论中的要求,它可以作为一个班轮完成 - 但正如我评论的那样, 它可以编写为适合作为一行中的单个表达式。写作比上面的例子花了更多的时间,并且几乎不可能维持。上面示例中的代码在几行代码中展开逻辑,这些代码被放置在“不在路上” - 即不是内联的实际数据,为两个任务提供可读性和可维护性。
也就是说,可以根据需要解析为嵌套列表的结构:
structure = [[[token.strip() for token in line.split(":")] for line in record.split("\n") ] for record in data.split("%%") if record.strip() ]
答案 1 :(得分:3)
作为一个单一的理解:
raw = """\
%%
Type: language
Subtag: aa
Description: Afar
Added: 2005-10-16
%%
Type: language
Subtag: ab
Description: Abkhazian
Added: 2005-10-16
Suppress-Script: Cyrl
%%
Type: language
Subtag: ae
Description: Avestan
Added: 2005-10-16
%%"""
data = [
dict(
row.split(': ')
for row in item_str.split("\n")
if row # required to avoid the empty lines which contained '%%'
)
for item_str in raw.split("%%")
if item_str # required to avoid the empty items at the start and end
]
>>> data[0]['Added']
'2005-10-16'
答案 2 :(得分:2)
答案 3 :(得分:2)
您可以使用itertools.groupby
:
ss = """%%
Type: language
Subtag: aa
Description: Afar
Added: 2005-10-16
%%
Type: language
Subtag: ab
Description: Abkhazian
Added: 2005-10-16
Suppress-Script: Cyrl
%%
Type: language
Subtag: ae
Description: Avestan
Added: 2005-10-16
"""
sss = ss.splitlines(True) #List which looks like you're iterating over a file object
import itertools
output = []
for k,v in itertools.groupby(sss,lambda x: x.strip() == '%%'):
if(k): #Hit a '%%' record. Need a new group.
print "\nNew group:\n"
current = {}
output.append(current)
else: #just a regular record, write the data to our current record dict.
for line in v:
print line.strip()
key,value = line.split(None,1)
current[key] = value
这个答案的一个好处是它不需要你阅读整个文件。整个表达式被懒惰地评估。