递归循环时的组列表

2024-09-28 20:38:18 发布

您现在位置:Python中文网/ 问答频道 /正文

这是我的输入和输出示例:

l = [
    ['random_str0', 'random_str', 'random_str'],
    ['random_str1', '', 'random_str'],
    ['random_str2', '', ''],
    ['random_str3', 'random_str', 'random_str'],
    ['random_str4', '', ''],
    ['random_str5', '', ''],
    ['random_str6', 'random_str', ''],
    ['random_str7', 'random_str', 'random_str'],
    ['random_str8', '', ''],
    ['random_str9', '', ''],
    ['random_str10', '', ''],
    ['random_str11', '', ''],
]


out = [ # something like this. data structure and type and order are not important
    ['random_str0', 'random_str', 'random_str'],
    [
        ['random_str1', '', 'random_str']
        ['random_str2', '', '']
    ],
    [
        ['random_str3', 'random_str', 'random_str'],
        ['random_str4', '', ''],
        ['random_str5', '', '']
    ],
    ['random_str6', 'random_str', ''],
    [
        ['random_str7', 'random_str', 'random_str'],
        ['random_str8', '', ''],
        ['random_str9', '', ''],
        ['random_str10', '', ''],
        ['random_str11', '', '']
    ]
]

如果任何内部列表具有索引1或索引2值,则后跟一个或多个缺少索引1和索引2值的列表,则形成一个组。(我的实际代码更复杂,也有其他条件,但为了简洁起见,省略了它,因为它不是实际问题的一部分。你知道吗

我就是这样试的。你知道吗

for n in reversed(range(1, 5)):
    for i in range(len(l)-n):
        group = [l[i+j] for j in range(n+1)]
        if (
            (group[0][1] or group[0][2]) and
            all([not (g[1] and g[2]) for g in group[1:]])
        ):
            print(group)

Out: # not desired as it is overlapping.
[
    ['random_str7', 'random_str', 'random_str'],
    ['random_str8', '', ''],
    ['random_str9', '', ''],
    ['random_str10', '', ''],
    ['random_str11', '', '']
]
[
    ['random_str7', 'random_str', 'random_str'],
    ['random_str8', '', ''],
    ['random_str9', '', ''],
    ['random_str10', '', '']
]
[
    ['random_str3', 'random_str', 'random_str'],
    ['random_str4', '', ''],
    ['random_str5', '', '']
]
[
    ['random_str7', 'random_str', 'random_str'],
    ['random_str8', '', ''],
    ['random_str9', '', '']
]
[
    ['random_str1', 'random_str', 'random_str'],
    ['random_str2', '', '']
]
[
    ['random_str3', 'random_str', 'random_str'],
    ['random_str4', '', '']
]
[
    ['random_str7', 'random_str', 'random_str'],
    ['random_str8', '', '']
]

问题是如何跟踪记录,使分组不重叠。我认为递归循环会有所帮助,但我不知道如何做到这一点。你知道吗

最终的数据结构不需要是一个列表。我用dicts试过了,但是代码变得更复杂了。你知道吗

为了进一步说明,我创建了一步一步的pastebinhttps://pastebin.com/qeWbxheK


Tags: andinforgrouprandomstrstr1str2
3条回答

您可以使用itertools.groupby

from itertools import groupby
d = [['random_str0', 'random_str', 'random_str'], ['random_str1', '', 'random_str'], ['random_str2', '', ''], ['random_str3', 'random_str', 'random_str'], ['random_str4', '', ''], ['random_str5', '', ''], ['random_str6', 'random_str', ''], ['random_str7', 'random_str', 'random_str'], ['random_str8', '', ''], ['random_str9', '', ''], ['random_str10', '', ''], ['random_str11', '', '']]
new_d = [list(b) for _, b in groupby(d, key=lambda x:not any(x[1:]))]
_d = [[*new_d[i][:-1], [new_d[i][-1], *new_d[i+1]]] for i in range(0, len(new_d), 2)]
result = [i for b in _d for i in b]

输出:

[
 ['random_str0', 'random_str', 'random_str'], 
 [['random_str1', '', 'random_str'], ['random_str2', '', '']], 
 [['random_str3', 'random_str', 'random_str'], ['random_str4', '', ''], ['random_str5', '', '']], 
 ['random_str6', 'random_str', ''], 
 [['random_str7', 'random_str', 'random_str'], ['random_str8', '', ''], ['random_str9', '', ''], ['random_str10', '', ''], ['random_str11', '', '']]
 ]

单回路:

import pprint

res = []
for sub_l in lst:   # lst is your initial list
    if sub_l[1] or sub_l[2]:
        res.append(sub_l)   # add as a base item of the group
    elif not sub_l[1] and not sub_l[2] and res:
        # check if last item is not a 2-dimensional list yet
        if not isinstance(res[-1][0], list): res[-1] = [res[-1]]
        res[-1].append(sub_l)

pprint.pprint(res)

输出:

[['random_str0', 'random_str', 'random_str'],
 [['random_str1', '', 'random_str'], ['random_str2', '', '']],
 [['random_str3', 'random_str', 'random_str'],
  ['random_str4', '', ''],
  ['random_str5', '', '']],
 ['random_str6', 'random_str', ''],
 [['random_str7', 'random_str', 'random_str'],
  ['random_str8', '', ''],
  ['random_str9', '', ''],
  ['random_str10', '', ''],
  ['random_str11', '', '']]]

您可以遍历该列表并尝试增加一个验证您的条件的项目窗口(同时item[1]item[2]计算为False)。为此,您可以有两个循环,一个循环将遍历窗口开始,另一个循环将在满足条件时放大窗口:

def cut(l):
    start = 0
    while start < len(l):
        end = start + 1
        while end < len(l) and not (l[end][1] or l[end][2]):
            end += 1
        yield l[start:end]
        start = end

然后可以这样使用此生成器:

for sublist in cut(l):
    print(sublist)
    print("----")

产生:

[['random_str0', 'random_str', 'random_str']]
----
[['random_str1', '', 'random_str'], ['random_str2', '', '']]
----
[['random_str3', 'random_str', 'random_str'], ['random_str4', '', ''], ['random_str5', '', '']]
----
[['random_str6', 'random_str', '']]
----
[['random_str7', 'random_str', 'random_str'], ['random_str8', '', ''], ['random_str9', '', ''], ['random_str10', '', ''], ['random_str11', '', 

如果只需要这些子列表的列表,可以使用list(cut(l))将生成器转换为列表。你知道吗

相关问题 更多 >