重新组织字典列表

Reorganize a list of dictionaries

假设我有以下内容:

[
  {"sku": "ZZZ", "name":"None name","shelf": 10},
  {"sku": "AAA", "name":"One name","shelf": 10},
  {"sku": "BBB", "name":"The name", "shelf": None},
  {"sku": "CCC", "name":"A name"}
]

我正在努力寻找最好的(也许是最优雅的)方式:

  1. 添加“架子”:缺少时'Default'或设置为None
  2. 按书架拆分列表,因此上面的列表应该给出两个命名列表:一个用于默认,一个用于“10” 这是所需的输出:
[
  {"10":[
    {"sku": "ZZZ", "name":"None name"},
    {"sku": "AAA", "name":"One name"}]
  },
  {"default":[
    {"sku": "CCC", "name":"A name"},
    {"sku": "BBB", "name":"The name"]
  }
]

使用 pydash.collections.for_each(initial_list,reorganize) 我可以解决第一个问题,但我不确定如何处理第二个问题。

def reorganize(x):
    if 'shelf' not in x: x['shelf'] = 'default'
    if x['shelf'] is None: x['shelf'] = 'default'

我也不认为这是解决问题的最好方法。 旋转列表的原因是因为我需要调用一个 API,它需要货架作为参数并且不能同时接受多个货架(但接受多个 SKU)。

input_list = [
  {"sku": "ZZZ", "name":"None name","shelf": 10},
  {"sku": "AAA", "name":"One name","shelf": 10},
  {"sku": "BBB", "name":"The name", "shelf": None},
  {"sku": "CCC", "name":"A name"}
]

output_dict = {}
for d in input_list:
    output_dict.setdefault(d.pop('shelf', 'default') or 'default', []).append(d)

output_dict 是:

{10: [{'sku': 'ZZZ', 'name': 'None name'}, {'sku': 'AAA', 'name': 'One name'}], 'default': [{'sku': 'BBB', 'name': 'The name'}, {'sku': 'CCC', 'name': 'A name'}]}

我们来解释一下代码:

  • pop returns shelf 条目并将其从字典中删除; 如果 shelf 不存在,则 pop returns 默认值,即它的 第二个(可选)参数(在本例中为 'default')。 or 是 用于处理存在 shelf 但带有 None 的情况 或 '' 值:在这种情况下,使用 default

  • setdefault returns键等于
    的字典的值 第一个参数,或者 returns 第二个参数,如果键是
    不存在。

  • append 将当前词典(shelf 条目被 pop 删除)添加到对应于其 shelf 值的列表中。

我对这个问题的看法, pandas:

df = pd.DataFrame([
  {"sku": "ZZZ", "name":"None name","shelf": 10},
  {"sku": "AAA", "name":"One name","shelf": 10},
  {"sku": "BBB", "name":"The name", "shelf": None},
  {"sku": "CCC", "name":"A name"}
])
df.shelf = df.shelf.fillna('default')
for shelf, skus in df.groupby('shelf').sku.apply(list).items():
    print(shelf, "=>", skus)
>>>
10.0 => ['ZZZ', 'AAA']
default => ['BBB', 'CCC']

lst = [
  {"sku": "ZZZ", "name":"None name","shelf": 10},
  {"sku": "AAA", "name":"One name","shelf": 10},
  {"sku": "BBB", "name":"The name", "shelf": None},
  {"sku": "CCC", "name":"A name"}
]

lst2 = list()
for dct in lst:
    v = dct.pop("shelf", None) or "default"
    for d in lst2:
        if d.get(v):
            d[v].append(dct)
            break
    else:
        lst2.append({v: [dct]})
print(lst2)

输出:

[{10: [{'sku': 'ZZZ', 'name': 'None name'},
       {'sku': 'AAA', 'name': 'One name'}]},
 {'default': [{'sku': 'BBB', 'name': 'The name'},
              {'sku': 'CCC', 'name': 'A name'}]}]

分解:

  1. 定义一个列表,lst2,成为输出列表。

  2. 遍历lst的字典,定义一个变量,v, 检查即将创建的字典的值是否应该是当前字典的 "shelf" 键的值,或者 "default".

  3. 遍历 lst2 的每个字典。如果找到相应的键,将字典附加到 lst2.

    的键