如何在Python中根据字符拆分字符串列表

3

我有一个字符串列表,格式如下:

org_list = ['', '<dialog xyz', 'string', 'more string', 'even more string etc', 
        '<dialog xyz', 'string', 'more string', 'even more string etc']

我需要将列表分成字符串的子列表,精确地在'<'字符上进行分割,以便每个字符串子列表都以'dialog xyz'开头。 样例输出:
[['<dialog xyz', 'string', 'more string', 'even more string etc'], ['<dialog 
  xyz', 'string', 'more string', 'even more string etc']]

我已经尝试使用列表推导式,但它没有起作用(返回相同的org_list):

divided_list = [s.split(',') for s in ','.join(org_list).split('<')]

我知道使用itertools可以实现(在一些答案中看到过),但是作为一个初学者,我并不太理解它们,如果可能的话,我想用我已经理解的方法解决这个问题。

8个回答

1
怎么样像这样简单的东西:
org_list = ['', '<dialog xyz', 'string', 'more string', 'even more string etc', '<dialog xyz', 'string', 'more string', 'even more string etc']
split_lists = [] 
for s in org_list:
  if s == '':
    continue
  if s.startswith('<') or len(split_lists) == 0: 
    split_lists.append([s])
    continue
  split_lists[-1].append(s)

print(split_lists)

输出:

[['<dialog xyz', 'string', 'more string', 'even more string etc'], ['<dialog xyz', 'string', 'more string', 'even more string etc']]

1
不要使用 if s is '' - juanpa.arrivillaga
is 是用于对象标识的,而不是用于相等性比较的。 - juanpa.arrivillaga
这对我来说是新的。个人而言,我觉得is更易读。 - Austin
这只是不正确的,因此可读性可能很重要,但正确性更重要。如果您正在使用单例,则is仅可与==互换,而在Python中单例非常罕见,但可能包括None、模块对象和类对象。 - juanpa.arrivillaga

1
首先,我们可以创建一个“索引”列表,该列表引用在“org_list”中字符串以“'<'”开头的位置。
然后,我们可以通过“list-comp”迭代这些索引,取每对索引之间的“slices”。
但是,在最后,我们注意到最后一个“slice”必须到达“org_list”的末尾,因此我们必须连接包含结束位置上方索引的“list”以捕获它。
希望您能看到如何将该描述转换为以下代码。
inds = [i for i, s in enumerate(org_list) if '<' in s] + [len(org_list)]
div_l = [org_list[inds[i]:inds[i+1]] for i in range(len(inds)-1)]

它会产生期望的输出:

[['<dialog xyz', 'string', 'more string', 'even more string etc'],
 ['<dialog xyz', 'string', 'more string', 'even more string etc']]

0

这应该可以工作:

split_lists = []
for s in org_list:
    if s.startswith('<') or len(split_lists) == 0:
        split_lists.append([])
    split_lists[-1].append(s)

这是您输入的结果:

>>> split_lists
[[''], ['<dialog xyz', 'string', 'more string', 'even more string etc'], ['<dialog xyz', 'string', 'more string', 'even more string etc']]

如果你想忽略在第一个以'<'开头的字符串之前的所有字符串,比如在你的org_list中的第一个空字符串,那么可以使用以下代码:
split_lists = []
for s in org_list:
    if s.startswith('<'):
        split_lists.append([])
    if len(split_lists) == 0:
        continue
    split_lists[-1].append(s)

0
org_list = ['', '<dialog xyz', 'ztring', 'more ztring', 'even more string etc', '<dialog xyz', 'string', 'more string', 'even more string etc']

orig = []
start = False

new = []

for item in org_list:
    if item == '<dialog xyz' or item == org_list[-1]:
        if len(new) > 1:
            orig.append(new)
        new = []
        start = True
    if start:
        new.append(item)

print(orig)

这将给你想要的输出。


0

这可能会有所帮助

org_list = ['', '<dialog xyz', 'string', 'more string', 'even more string etc',
        '<dialog xyz', 'string', 'more string', 'even more string etc']

result = [i.split("|") if i.startswith("<") else ("<"+i).split("|") for i in "|".join(filter(None, org_list)).split("|<")]
print result

输出:

[['<dialog xyz', 'string', 'more string', 'even more string etc'], ['<dialog xyz', 'string', 'more string', 'even more string etc']]

0
你可以使用 itertools.groupby:
import itertools
import re
org_list = ['', '<dialog xyz', 'string', 'more string', 'even more string etc', 
    '<dialog xyz', 'string', 'more string', 'even more string etc']
new_list = [list(b) for a, b in itertools.groupby(filter(None, org_list), key=lambda x:bool(re.findall('^\<dialog', x)))]
final_list = [new_list[i]+new_list[i+1] for i in range(0, len(new_list), 2)]

输出:

[['<dialog xyz', 'string', 'more string', 'even more string etc'], ['<dialog xyz', 'string', 'more string', 'even more string etc']]

0

比赛。谁能让函数更加复杂和缓慢。简单点,这是Python。

org_list = ['', '<dialog xyz', 'string', 'more string', 'even more string etc', 
        '<dialog xyz', 'string', '', 'even more string etc' , '<dialog xyz', 'string', 'more string',]

def slicelist (pred, iterable):
    element = []
    alw = False
    for s in iterable:
         sw = s.startswith
         if sw(pred):
                element.append([])
                alw=True
         if alw :        
                element[-1].append(s)
    return element

print slicelist('<', org_list)

如果你想要创建生成器(迭代器),你需要在上面的例子中更改next操作符:将return改为yield,并将print slicelist('<', org_list)改为print list(slicelist('<', org_list))

0
你可以像这样做:
org_list = ['', '<dialog xyz', 'string', 'more string', 'even more string etc',
        '<dialog xyz', 'string', 'more string', 'even more string etc']



flag=True
sub_list=[]
final_list=[]
text='<dialog xyz'
for i in org_list:
    if i.startswith(text):


        flag=False

        if sub_list:
            sub_list.insert(0,text)
            final_list.append(sub_list)

            sub_list=[]

    else:
        if flag==False:



            sub_list.append(i)
sub_list.insert(0,text)
final_list.append(sub_list)
print(final_list)

输出:

[['<dialog xyz', 'string', 'more string', 'even more string etc'], ['<dialog xyz', 'string', 'more string', 'even more string etc']]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接