级联字符串拆分,python方式

级联字符串拆分,python方式,python,python-2.7,Python,Python 2.7,以IANA的这种格式为例: 假设我打开文件: import urllib f = urllib.urlopen("http://www.iana.org/assignments/language-subtag-registry") all=f.read() 通常你会喜欢这个 lan=all.split("%%") 迭代lan和split(“\n”)然后迭代结果和split(“:”),是否有办法在python中一批完成此操作而不进行迭代,并且输出仍然如下所示: [[“Type”、“langu

以IANA的这种格式为例:

假设我打开文件:

import urllib
f = urllib.urlopen("http://www.iana.org/assignments/language-subtag-registry")
all=f.read()
通常你会喜欢这个

lan=all.split("%%") 
迭代lan和
split(“\n”)
然后迭代结果和split(“:”),是否有办法在python中一批完成此操作而不进行迭代,并且输出仍然如下所示:
[[“Type”、“language”]、[“Subtag”、“ae”]、…]

如果在每次拆分后得到的元素在语义上不同,那么尝试在一个过程中完成这项工作没有任何意义

您可以从“:”开始拆分,这将使您获得细粒度数据,但如果您不知道这些数据属于什么,这又有什么好处呢

这就是说,你可以把所有的分离水平放在一个发电机里,让它产生 已准备好使用数据的dictionary对象:

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() ]

如果您在每次拆分后得到的元素在语义上是不同的,那么我认为在一次传递中尝试这样做没有任何意义

您可以从“:”开始拆分,这将使您获得细粒度数据,但如果您不知道这些数据属于什么,这又有什么好处呢

这就是说,你可以把所有的分离水平放在一个发电机里,让它产生 已准备好使用数据的dictionary对象:

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() ]
,但我看不出重点:

re.split('%%|:|\\n', string)
这里使用or
|
操作符链接了多个模式。

,但我看不出要点:

re.split('%%|:|\\n', string)

这里使用or
|
操作符链接了多个模式。

您可以使用
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

这个答案的一个好处是,它不需要您读取整个文件。整个表达式是惰性计算的。

您可以使用
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

这个答案的一个好处是,它不需要您读取整个文件。整个表达式的计算是惰性的。

作为单个理解:

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
]

作为一种理解:

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
]

因此,如果不进行迭代,就不可能得到像这样的
[[[“Type”,“language”],[“Subtag”,“ae”],…]
。@EduardFlorinescu不可能,而且如果调用函数来生成输出,它会在内部进行迭代,那么迭代有什么不好的地方呢?它可以写成一行中的单个表达式。它比上面的例子需要更多的时间来编写,而且几乎不可能维护。上面示例中的代码在几行代码中展开逻辑,这些代码放在“不在ay”的位置,即不在您处理实际数据的位置内联,为这两项任务提供可读性和可维护性。@jsbueno:+1用于猜测此处的目的并为其提供漂亮的生成器。@EduardFlorinescu:试试看,它总是返回一个三元组。新的第8行应该是:
key,value=line.partition(':')[::2]
(或者
key,_uz,value=line.partition(':')
),但是要警惕绑定到其gettext函数的
i18n
模块的问题。因此不可能像这样得到它没有迭代吗?@EduardFlorinescu不太可能,而且如果你调用一个函数来生成这个输出,它会在内部迭代,那么迭代有什么不好呢?它可以写成一行中的一个表达式。它比上面的例子需要更多的时间来编写,而且几乎不可能维护。代码在上面的示例中,在几行代码中展开逻辑,这些代码放在“ay之外”-也就是说,不内联处理实际数据,为这两项任务提供可读性和可维护性。@jsbueno:+1用于猜测此处的目的并为其提供一个漂亮的生成器。@EduardFlorinescu:试试看,它总是返回一个三元组。新行8将读取:
key,value=line.partition(':')[:2]
(或
键,值=行.partition(“:”)
但是要小心将
绑定到其gettext函数的
i18n
模块的问题。但是,你不知道一个记录何时结束,下一个记录何时开始,除非你硬编码要求每个记录必须以
Type
字段开始。例如,你还使f中不可能有分隔符字段值,在这种情况下这可能不是一个严重的问题(和/或如果您愿意,您可以在
%%
的两侧都要求换行)。@tripleee:使用先行模式拆分如何?我可以对分隔符执行相同的操作(它们必须转义,或者您假设一个只使用第一个分隔符)。如果您感兴趣,我可以为您展示一些正则表达式,但您也可以直接访问awnser中链接的正则表达式文档。此外,这只是一个awnser,用于执行用户要求的操作