如何将列表中的元素组合到新的嵌套列表中?

Posted

技术标签:

【中文标题】如何将列表中的元素组合到新的嵌套列表中?【英文标题】:How to combine elements in list to a new nested list? 【发布时间】:2018-04-25 05:31:02 【问题描述】:

我有一个这样的列表“r”:

[["", 1], ["this is a text line", 2], ["this is a text line", 3], ["this is a text line", 4], ["", 5], ["", 6], ["this is a text line", 7],["this is a text line", 8], ["this is a text line", 9], ["this is a text line", 10], ["", 11], ["this is a text line", 12], ["this is a text line", 13], ["this is a text line", 14], ["", 15], ["this is a text line", 16], ["this is a text line", 17], ["this is a text line", 18], ["", 19]]

要知道我的空行和带有文本的行在哪里,我过滤了我的列表:

empty = [x[1] for x in r if regex.search("^\s*$", x[0])]
text = [x[1] for x in r if regex.search("\S", x[0])]

输出:

empty = [1, 5, 6, 11, 15, 19]
text= [2, 3, 4, 7, 8, 9, 10, 12, 13, 14, 16, 17, 18]

我想要做的是组合文本中的数字,如果它们是按顺序排列的 (text[i]-text[i+1]) = +1(为了定义段落):

finaltext = [[2, 3, 4], [7, 8, 9, 10], [12, 13, 14], [16, 17, 18]]
finaltext including empty = [[2, 3, 4, 5, 6], [7, 8, 9, 10, 11], [12, 13, 14, 15], [16, 17, 18, 19]]

如何根据条件对列表中的元素进行分组?

【问题讨论】:

您需要finaltextfinaltext_including_empty 还是只需要最后一个?为什么finaltext_including_empty的第一个子列表不是以1开头的? 我需要两个列表。第一个子列表不以 1 开头,因为我不考虑文本开头的空行。 【参考方案1】:

使用itertools.groupby

from itertools import groupby, zip_longest
grp_list = [list(g) for k,g in groupby(r, lambda x:x[0]=='')]
grp_list = grp_list[1:] if r[0][0] == '' else grp_list
text = [[j[1] for j in i] for i in grp_list]

finaltext = text[::2]
print (finaltext)
#[[2, 3, 4], [7, 8, 9, 10], [12, 13, 14], [16, 17, 18]]

finaltext_including_empty = [i+j for i,j in zip_longest(text[::2], text[1::2], fillvalue=[])]
print (finaltext_including_empty)
#[[2, 3, 4, 5, 6], [7, 8, 9, 10, 11], [12, 13, 14, 15], [16, 17, 18, 19]]

groupby 根据lambda x:x[0]=='' 的条件将列表分组为子列表块,这意味着创建一个列表块直到您看到一个空字符串为止,并遵循此规则直到结束,如下所示

[[['', 1]], [['this is a text line', 2], ['this is a text line', 3], ['this is a text line', 4]], [['', 5], ['', 6]],........]

【讨论】:

迷人。有点好奇为什么 groupby 会创建 9 个组而不是 2 个:空的和非空的? 请看我对 groupby 的评论 感谢您的解决方案!但是我注意到,如果我的示例列表的第一行是文本,它就不再起作用了。 (finaltext 捕获空行 [1::2]) @TransHumanist,还是有一些东西不工作。请取空列表 [1, 5, 10, 15, 20] 和文本列表 [2, 3, 4, 6, 7, 8, 9, 11, 12, 13, 14, 16, 17, 18, 19 , 21]。然后使用您的解决方案,它将结果作为决赛名单: [[1, 2, 3, 4], [6, 7, 8, 9], [11, 12, 13, 14], [16, 17, 18, 19 , 20, 21]]。包含几个空格(1 和 20 不能在列表中) 好的,现在编辑以包含 zip_longest,您应该会看到它。让我知道。【参考方案2】:

没有任何modules的纯Python解决方案:

这可以使用modules 来完成,例如numpygroupby,但我认为没有它们会被调用,只需使用简单的Python。这是我的解决方案:

text = [2, 3, 4, 7, 8, 9, 10, 12, 13, 14, 16, 17, 18]
s = 0
finaltext = []
for i in range(len(text)-1):
    if text[i] + 1 != text[i+1]:
        finaltext.append(text[s:i+1])
        s = i+1

finaltext.append(text[s:])

finaltext 设为:

[[2, 3, 4], [7, 8, 9, 10], [12, 13, 14], [16, 17, 18]]

更新

要同时获得lists(不知道为什么要这样做),您可以使用以下命令:

empty = [1, 5, 6, 11, 15, 19]
text = [2, 3, 4, 7, 8, 9, 10, 12, 13, 14, 16, 17, 18]
s = 0
finaltext = []
finaltext_including_empty = []
for i in range(len(text)-1):
    if text[i] + 1 != text[i+1]:
        finaltext.append(text[s:i+1])
        finaltext_including_empty.append(list(range(text[s], text[i+1])))
        s = i+1

finaltext.append(text[s:])
finaltext_including_empty.append(list(range(text[s],max(empty[-1]+1, text[-1]+1))))

这使得finaltext 与以前相同,finaltext_including_empty 为:

[[2, 3, 4, 5, 6], [7, 8, 9, 10, 11], [12, 13, 14, 15], [16, 17, 18, 19]]

【讨论】:

这不是所需的操作。最后一个子列表应该是 [16,17,18] @sharatpc 对此感到抱歉,这只是我没有收到的最后一行中的一个小错误,现在看看 - 我对任何其他问题持开放态度 :) 感谢您的回答。非常简单和漂亮。但是..在'finaltext_include_empty'中缺少19。 @Reman,我的错,我不明白为什么这是必要的,但我现在已经更新了答案到 empty list 的末尾(即包括 @987654336 @) 希望这会有所帮助! @JoeIddon 如果您将 [1, 5, 10, 15, 20] 作为空列表并且将 [2, 3, 4, 6, 7, 8, 9, 11, 12, 13, 14 , 16, 17, 18, 19, 21] 作为文本列表,它给出了错误的“finaltext_including_empty”输出。不包括 21 个【参考方案3】:

pip install more_itertools

from more_itertools import chunked

empty = [1, 5, 6, 11, 15, 19]
text= [2, 3, 4, 7, 8, 9, 10, 12, 13, 14, 16, 17, 18]

finaltext_ = sorted(empty + text)

list(chunked(finaltext_,4))
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16], [17, 18, 19]]

【讨论】:

操作无效。 Asker 不希望将这两个列表合并,而是将文本中的数字分成子序列。将块大小硬编码为 4?如果文本包含大小不等的块怎么办?

以上是关于如何将列表中的元素组合到新的嵌套列表中?的主要内容,如果未能解决你的问题,请参考以下文章

如何比较字典值中的多个数组,并将每个数组元素的字典键映射到新数组/列表中

Python中嵌套列表中的列表组合

如何迭代地将 2 个列表中的元素应用到新函数中? [复制]

python中flat将嵌套列表中的元素按顺序排列在一个列表中

Python中将列表元素嵌套到数据框

如何更改嵌套列表中的元素?