You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将多层嵌套可迭代对象压缩为单次可迭代元组集合

处理嵌套层级不一致的可迭代对象

核心定义

若对象所有元素均为可迭代对象,则为多次可迭代;
若对象所有元素均不可迭代,则为单次可迭代;
若对象元素均为含非可迭代元素的可迭代对象,则为两次可迭代,例如((1,),(1,2,),(1,2,3,))。

输入示例

trie_like= ( ((((('a','b','c','d'),), (('a','b','c','e'),),), ((('a','b','d','e'),),),), (((('a','c','d','e'),),),),), ((((('b','c','d','e'),),),),), )
uneven = (((1,),(2,),(3,)),((1,2,3),), (12,34),)

需求

编写函数降低嵌套层级,将原始对象解包至两次可迭代层级,即压缩后的可迭代对象每个元素均为单次可迭代元组。预期输出:

trie_like_condensed = (('a','b','c','d'),('a','b','c','e'),('a','b','d','e'), ('a','c','d','e'),('b','c','d','e'),)
uneven_condensed = ((1,),(2,),(3,),(1,2,3),(12,34),)

尝试过的方法及问题

  1. 反复调用itertools.chain.from_iterable:无法确定终止条件,仅适配嵌套深度完全一致的对象,对于层级不均的输入会过度展开或展开不足。

    import itertools
    from collections.abc import Iterable
    
    t = ( ((((('a','b','c','d'),), (('a','b','c','e'),),), ((('a','b','d','e'),),),), (((('a','c','d','e'),),),),), ((((('b','c','d','e'),),),),),)
    
    count = 0 # 防止无限循环
    while isinstance(t,Iterable) and count<20:
        count = count + 1
        t,p = itertools.tee(itertools.chain.from_iterable(t))
        print(list(p))
    print(*map("".join, t))
    
  2. itertools.takewhile递归实现:未正确区分需要保留的层级和需要展开的层级,逻辑混乱导致无法得到预期结果。

    import itertools
    from collections.abc import Iterable
    
    def unnest_iterables(t,count=0):
        iter_part = itertools.takewhile(lambda x: isinstance(x,Iterable),t)
        niter_part = itertools.takewhile(lambda x: not isinstance(x,Iterable),t)
        # 复制迭代器用于打印
        iter_part,p = itertools.tee(iter_part)
        niter_part,pn = itertools.tee(niter_part)
        print(f'Depth = {count}: {list(p)} : {list(pn)}')
        if count > 10:
            print('TEST: Big oof')
            return []
        try:
            return unnest_iterables(itertools.chain(itertools.chain.from_iterable(iter_part),niter_part),count+1)
        except StopIteration:
            return itertools.chain(itertools.chain.from_iterable(iter_part),niter_part)
    
    
    t = ( (((((1,2,3,4),), ((1,2,3,5),),), (((1,2,4,5),),),), ((((1,3,4,5),),),),), (((((2,3,4,5),),),),),)
    print(*unnest_iterables(t))
    

解决方案

通过递归遍历,判断每个元素是否需要继续展开:仅当元素是多次可迭代(自身可迭代且所有子元素均为可迭代)时,才递归展开;否则直接保留该元素(已符合单次可迭代的要求)。

from collections.abc import Iterable

def flatten_to_single_iterables(iterable):
    result = []
    for item in iterable:
        # 判断当前元素是否为多次可迭代:需要继续展开
        if isinstance(item, Iterable) and all(isinstance(sub, Iterable) for sub in item):
            result.extend(flatten_to_single_iterables(item))
        else:
            # 当前元素已是单次可迭代,直接保留
            result.append(item)
    return tuple(result)

测试验证

# 测试trie_like
trie_like= ( ((((('a','b','c','d'),), (('a','b','c','e'),),), ((('a','b','d','e'),),),), (((('a','c','d','e'),),),),), ((((('b','c','d','e'),),),),), )
print(flatten_to_single_iterables(trie_like))
# 输出:(('a', 'b', 'c', 'd'), ('a', 'b', 'c', 'e'), ('a', 'b', 'd', 'e'), ('a', 'c', 'd', 'e'), ('b', 'c', 'd', 'e'))

# 测试uneven
uneven = (((1,),(2,),(3,)),((1,2,3),), (12,34),)
print(flatten_to_single_iterables(uneven))
# 输出:((1,), (2,), (3,), (1, 2, 3), (12, 34))

逻辑说明

  • 遍历输入的每个元素,检查其是否属于需要继续展开的“多次可迭代”类型;
  • 对于需要展开的元素,递归处理后将结果合并到最终列表;
  • 对于不需要展开的元素(单次可迭代元组),直接加入结果列表;
  • 最终将结果转为元组,符合输入输出的类型一致性。

内容的提问来源于stack exchange,提问作者Orion Yeung

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 03:25:27