将列表中的元素分组

时间:2019-10-08 16:02:10

标签: python text-mining

我想对列表中的元素进行分组-每个组都有定义的开始和结束:

data = ['§349', 'Abs.', '2', '4', 'StPO', '1', '3', '42', '§306a', 'Abs.', '1', 'Nr.', '1', 'StGB', '§306b', 'Abs.', '2', 'Nr.', '2', 'StGB', '§306b', 'Abs.', '2', 'Nr.', '2', 'StGB', '§306a', '§306b', 'Abs.', '2', 'Nr.', '2', 'StGB', '2', '3', '4', '5', '4', '§306a', 'Abs.', '1', 'Nr.', '1', 'StGB', '10', '16', '26', '2', 'StR', '76', '§306a', 'Abs.', '1', 'Nr.', '1', 'StGB', '2', 'StR', '2', 'StR', '76', 'StGB', '§306a', '§306a', '§306a', '§306', 'Abs.', '1', 'Nr.', '1', 'StGB']

所需的输出= ['§349|Abs.2|4|StPO', '§306a|Abs.1|Nr.1|StGB', '§306b|Abs.2|Nr.2|StGB', '§306b|Abs.2|Nr.2|StGB', (...)]

开始:"§"

结尾:"StPO""StGB"

列表中的每个元素应首先以符号“§”开头,并以“ StGB”或“ StPO”结尾。如果在StPO或StGB之后,下一个元素不是以§开头,则将其删除,直到达到§。每个元素都应以“ |”连接,但如果元素为“ Abs”则不可以。或“ Nr”。 -在这种情况下,下一个元素应仅连接而没有分隔符。

4 个答案:

答案 0 :(得分:1)

这是一种简单的方法。在这里,只需添加额外的elif语句即可限制字符串的形成:

out = []
f = False
for i in data:
    if i.startswith('§'):
        l = i[:]
    elif i.startswith(('StPO','StGB')):
        l += f'|{i}'
        out.append(l)
        l = ''
    elif i.startswith(('Abs.','Nr.')):
        f = True
        tmp = i[:]
    else:    
        if f:
            l += f'|{tmp}{i}'
            f = False
        else:
            l += f'|{i}'

print(out)

['§349|Abs.2|4|StPO',
 '§306a|Abs.1|Nr.1|StGB',
 '§306b|Abs.2|Nr.2|StGB',
 '§306b|Abs.2|Nr.2|StGB',
 '§306b|Abs.2|Nr.2|StGB',
 '§306a|Abs.1|Nr.1|StGB',
  ...

答案 1 :(得分:0)

希望这会有所帮助

def t(data):
    start = []
    end, e = [], True 
    rs = []  
    for i,n in enumerate(data):
        if n.startswith('§'):
            if e:
                start.append(i)
                e = False
        elif n.startswith('St'):
            end.append(i)
            e = True 
    for v in range(len(start)):
        k,l=start[v], end[v]
        d = '|'.join(data[k:l+1]).replace('Abs.|', 'Abs.').replace('Nr.|', 'Nr.')
        if d:
            rs.append(d)

rs = t(data)
print(rs)

答案 2 :(得分:0)

使用正则表达式和替换的另一种方法:

import re

data = ['§349', 'Abs.', '2', '4', 'StPO', '1', '3', '42', '§306a', 'Abs.', '1', 'Nr.', '1', 'StGB', '§306b', 'Abs.', '2', 'Nr.', '2', 'StGB', '§306b', 'Abs.', '2', 'Nr.', '2', 'StGB', '§306a', '§306b', 'Abs.', '2', 'Nr.', '2', 'StGB', '2', '3', '4', '5', '4', '§306a', 'Abs.', '1', 'Nr.', '1', 'StGB', '10', '16', '26', '2', 'StR', '76', '§306a', 'Abs.', '1', 'Nr.', '1', 'StGB', '2', 'StR', '2', 'StR', '76', 'StGB', '§306a', '§306a', '§306a', '§306', 'Abs.', '1', 'Nr.', '1', 'StGB']
data_str = "|".join(data)

patt = re.compile("(§[^§]*?St(PO|GB))")

search_res = re.findall(patt, data_str)
output = [each[0].replace("Abs.|", "Abs.").replace("Nr.|", "Nr.") for each in search_res]

print(output)

输出:

[
    '§349|Abs.2|4|StPO', 
    '§306a|Abs.1|Nr.1|StGB', 
    '§306b|Abs.2|Nr.2|StGB', 
    '§306b|Abs.2|Nr.2|StGB', 
    '§306b|Abs.2|Nr.2|StGB', 
    '§306a|Abs.1|Nr.1|StGB', 
    '§306a|Abs.1|Nr.1|StGB', 
    '§306|Abs.1|Nr.1|StGB'
]

答案 3 :(得分:-1)

对不起,我没有注意“结束”部分。 编辑后,尝试:

代码:

desired_output = [item
                  [:item.find("StPO")+4 if item.find("StPO") > 0 else None]
                  [:item.find("StGB")+4 if item.find("StGB") > 0 else None]
                  for item in "|".join(data).replace("§", "&§").split("&")
                  if ("StPO" in item or "StGB" in item) and "§" in item]

结果:

desired_output = [
'§349|Abs.|2|4|StPO',
'§306a|Abs.|1|Nr.|1|StGB',
'§306b|Abs.|2|Nr.|2|StGB',
'§306b|Abs.|2|Nr.|2|StGB',
'§306b|Abs.|2|Nr.|2|StGB',
'§306a|Abs.|1|Nr.|1|StGB',
'§306a|Abs.|1|Nr.|1|StGB',
'§306|Abs.|1|Nr.|1|StGB']