【问题标题】:Python: split a dict in a list [duplicate]Python:在列表中拆分字典[重复]
【发布时间】:2018-05-01 10:49:06
【问题描述】:

我想将一个简单的 dict 像这样:d = {0:0, 1:1, 2:2, 3:3} 转换为一个 dict 列表,其中每个(或更多)的元素数量与这个:[{0:0, 2:2}, {1:1, 3:3}] 相同。我尝试过像列表一样使用简单的索引,但它给我带来了TypeError: unhashable type: 'slice'。这是我现在拥有的:

def dico_chunks(dico, n):
    if len(dico) < n:
        n = len(dico)
    return [dico[i::n] for i in range(n)]

请记住,无论如何我都不需要对列表进行排序。我只需要将我的主字典拆分为n 子字典列表。

【问题讨论】:

  • 您需要决定将哪些元素放入列表内的同一字典中的规则。
  • 字典是无序的集合,项目没有与之关联的自然索引号。您可以拆分 dict 的键列表,但请记住,该列表可能不是您期望的顺序。
  • 你能把分割的规则更清楚一点吗?
  • 我需要主字典中的每个值在任何子字典中只出现一次。我只需要将我的主字典拆分为多个较小的字典 (n),每个子字典中的值数量相同。
  • 链接问题中接受的答案是否符合您的要求?

标签: python list dictionary


【解决方案1】:

您可以使用Iterate through pairs of items in a Python list 中定义的pairwise 函数来执行此操作,并将字典的items() 传递给它:

from itertools import tee

def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return zip(a, b)

d = {0:0, 1:1, 2:2, 3:3}

list(map(dict,pairwise(d.items())))
# [{0: 0, 1: 1}, {1: 1, 2: 2}, {2: 2, 3: 3}]

如果你想要不重复的对,那么你可以使用zip:

items = list(d.items())

list(map(dict, zip(items[::2], items[1::2])))
# [{0: 0, 1: 1}, {2: 2, 3: 3}]

字典基本上是无序的,所以如果你想要一个特定的顺序,你需要使用其他逻辑来指定它。

【讨论】:

    【解决方案2】:

    基于生成器的方法:

    def chunk_dict(d, chunk_size):
        r = {}
        for k, v in d.items():
            if len(r) == chunk_size:
                yield r
                r = {}
            r[k] = v
        if r:
            yield r
    
    d = {1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6}
    list(chunk_dict(d, 2))
    # [{1: 1, 2: 2}, {3: 3, 4: 4}, {5: 5, 6: 6}]
    

    相同功能的更短且性能更高的版本(使用itertools.islice) 可以在this answer找到。

    对于给定数量的尽可能均匀分布的块(例如,大小为 4、4、3、3 而不是 4、4、4、2),您可以这样做:

    chunks = [{} for _ in range(num_chunks)]
    for i, k in enumerate(d):
        chunks[i % num_chunks][k] = d[v]
    

    【讨论】:

    • 我收到的不是chunk_size arg,而是number_of_chunks,它决定了块大小本身。
    • chunk_size = len(d) // num_chunks 或类似的东西会让你从一个到另一个。
    • FWIW,我打算发布类似:items = sorted(dico.items())n = min(n, len(dico))return [dict(items[i::n]) for i in range(n)]...
    • @Marc-AntoineGiguère 你可能想玩弄我刚刚在我之前的评论中添加的代码。
    • @PM2Ring 是的,这是更聪明(也许更神秘)的版本 :)
    猜你喜欢
    • 2013-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-24
    • 1970-01-01
    • 1970-01-01
    • 2010-12-19
    相关资源
    最近更新 更多