拼合列表的字典词典(深2级)

发布于 2021-01-29 14:10:53

我正在尽全力解决这个问题,但是不够灵活。

在我的Python脚本中,我有一个字典列表字典。(实际上,它会更深入一点,但该级别不涉及此问题。)我想将所有这些内容整理成一个很长的列表,扔掉所有的字典键。

因此我想转型

{1: {'a': [1, 2, 3], 'b': [0]},
 2: {'c': [4, 5, 1], 'd': [3, 8]}}

[1, 2, 3, 0, 4, 5, 1, 3, 8]

我可能可以设置一个map-reduce来迭代外部词典的各项,以从每个子词典构建一个子列表,然后将所有子列表连接在一起。

但这对于大型数据集似乎效率不高,因为中间的数据结构(子列表)将被丢弃。有一种方法可以一次完成吗?

除非如此,否则我很乐意接受一个有效的两级实现…我的map-reduce生锈了!

更新: 对于那些感兴趣的人,下面是我最终使用的代码。

注意,尽管我在上面要求一个列表作为输出,但我真正需要的是一个有序列表。即,展平的输出可以是可以排序的任何可迭代的。

def genSessions(d):
    """Given the ipDict, return an iterator that provides all the sessions,
    one by one, converted to tuples."""
    for uaDict in d.itervalues():
        for sessions in uaDict.itervalues():
            for session in sessions:
                yield tuple(session)

# Flatten dict of dicts of lists of sessions into a list of sessions.
# Sort that list by start time
sessionsByStartTime = sorted(genSessions(ipDict), key=operator.itemgetter(0))
# Then make another copy sorted by end time.
sessionsByEndTime = sorted(sessionsByStartTime, key=operator.itemgetter(1))

再次感谢所有提供帮助的人。

[更新:替换nthGetter()operator.itemgetter(),感谢@intuited]

关注者
0
被浏览
85
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    编辑 :重新阅读原始问题和重新设计的答案,以假定所有非词典都是要拼合的列表。

    如果您不确定字典的使用范围,可以使用递归函数。@Arrieta已经发布了一个函数,该函数以递归方式构建非字典值列表。

    这是一个生成器,它在字典树中产生连续的非字典值:

    def flatten(d):
        """Recursively flatten dictionary values in `d`.
    
        >>> hat = {'cat': ['images/cat-in-the-hat.png'],
        ...        'fish': {'colours': {'red': [0xFF0000], 'blue': [0x0000FF]},
        ...                 'numbers': {'one': [1], 'two': [2]}},
        ...        'food': {'eggs': {'green': [0x00FF00]},
        ...                 'ham': ['lean', 'medium', 'fat']}}
        >>> set_of_values = set(flatten(hat))
        >>> sorted(set_of_values)
        [1, 2, 255, 65280, 16711680, 'fat', 'images/cat-in-the-hat.png', 'lean', 'medium']
        """
        try:
            for v in d.itervalues():
                for nested_v in flatten(v):
                    yield nested_v
        except AttributeError:
            for list_v in d:
                yield list_v
    

    doctest将结果迭代器传递给set函数。这很可能就是您想要的,因为正如Martelli先生所指出的那样,字典值没有内在顺序,因此没有理由跟踪它们的查找顺序。

    您可能需要跟踪每个值的出现次数;如果将迭代器传递给,则此信息将丢失set。如果您想跟踪它,只需将的结果传递flatten(hat)给其他函数而不是即可set。在Python
    2.7下,该其他函数可以是collections.Counter。为了与发展程度较低的python兼容,您可以编写自己的函数,或者(在效率方面有所损失)sorted与结合使用itertools.groupby



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看