【问题标题】:Nest a flat list based on an arbitrary criterion基于任意标准嵌套一个平面列表
【发布时间】:2015-07-23 18:16:46
【问题描述】:

我有一个独特对象的平面列表,其中一些可能与其他对象共享给定属性。我希望创建一个嵌套列表,其中对象按给定属性分组。作为一个最小的例子,给定以下列表:

>>> flat = ["Shoes", "pants", "shirt", "tie", "jacket", "hat"]

我可能想按长度分组,例如:

>>> nest_by_length(flat)
[['tie', 'hat'], ['shoes', 'pants', 'shirt'], ['jacket']]

我见过几个similar questions 和suggestions。但是,在所有这些情况下,嵌套都是基于输入列表的顺序。在我的例子中,输入列表的顺序是完全不可预测的,输出的子列表数量和每个子列表的项目数也是如此。

是否有标准的功能或惯用的方法来完成此操作?

【问题讨论】:

    标签: python list


    【解决方案1】:

    现有列表的常见用法是在 itertools 中使用 groupby:

    from itertools import groupby
    
    flat = ["Shoes", "pants", "shirt", "tie", "jacket", "hat"]
    
    result=[]
    for k, g in groupby(sorted(flat, key=len), key=len):
        result.append(list(g))
    
    print result   
    

    或者,更简洁:

    [list(g) for _,g in groupby(sorted(flat, key=len), key=len)]
    

    打印:

    [['tie', 'hat'], ['Shoes', 'pants', 'shirt'], ['jacket']]
    

    groupby 的输入根据键功能输出的变化值分组,在本例中为len。一般需要根据相同的key函数对列表进行预排序,所以先调用sorted函数。

    如果您的源列表尚未完成,或者无法根据条件排序(或者您只是更喜欢其他选项),请创建一个将您的条件映射到唯一键值的 dict:

    groups={}
    for e in flat:
        groups.setdefault(len(e), []).append(e)
    
    print groups    
    # {5: ['Shoes', 'pants', 'shirt'], 3: ['tie', 'hat'], 6: ['jacket']}
    

    您也可以使用defaultdict 而不是 setdefault 与任意键值:

    from collections import defaultdict
    groups=defaultdict(list)
    for e in flat:
        groups[len(e)].append(e)  
    # groups=defaultdict(<type 'list'>, {5: ['Shoes', 'pants', 'shirt'], 3: ['tie', 'hat'], 6: ['jacket']})
    

    在任何一种情况下,您都可以从中创建嵌套列表:

    >>> [groups[k] for k in sorted(groups.keys())] 
    [['tie', 'hat'], ['Shoes', 'pants', 'shirt'], ['jacket']]
    

    【讨论】:

    • 感谢您的周到。我怀疑会有一些我不知道的像 groupby 这样的功能,但是字典技巧很聪明。谢谢!
    猜你喜欢
    • 2022-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-24
    • 1970-01-01
    • 2018-06-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多