Python - itertools.groupby 2

Python - itertools.groupby 2

只是遇到了 itertools.groupby 的问题。给定一个字典列表,

my_list= [ 
"AD01", "AD01AA", "AD01AB", "AD01AC", "AD01AD","AD02", "AD02AA", "AD02AB", "AD02AC"]

根据这个列表,我希望创建一个字典,其中键是最短的名字,值是最长的名字

例子

[
{"Legacy" : "AD01", "rphy" : ["AD01AA", "AD01AB", "AD01AC", "AD01AD"]},
{"Legacy" : "AD02", "rphy" : ["AD02AA", "AD02AB", "AD02AC"]},
]

你能帮帮我吗

您可以使用 itertools.groupby 和一些 nexts:

from itertools import groupby

my_list= ["AD01", "AD01AA", "AD01AB", "AD01AC", "AD01AD","AD02", "AD02AA", "AD02AB", "AD02AC"]

groups = groupby(my_list, len)
output = [{'Legacy': next(g), 'rphy': list(next(groups)[1])} for _, g in groups]

print(output)
# [{'Legacy': 'AD01', 'rphy': ['AD01AA', 'AD01AB', 'AD01AC', 'AD01AD']},
#  {'Legacy': 'AD02', 'rphy': ['AD02AA', 'AD02AB', 'AD02AC']}]

对输入列表的重新排序不稳健。

此外,如果输入中存在一些“间隙”,例如,如果 "AD01" 没有相应的 'rphy' 条目,那么它会在您输入时抛出 StopIteration 错误发现了。在这种情况下,您可以使用更传统的方法:

from itertools import groupby

my_list= ["AD01", "AD02", "AD02AA", "AD02AB", "AD02AC"]

output = []
for item in my_list:
    if len(item) == 4:
        dct = {'Legacy': item, 'rphy': []}
        output.append(dct)
    else:
        dct['rphy'].append(item)

print(output)
# [{'Legacy': 'AD01', 'rphy': []}, {'Legacy': 'AD02', 'rphy': ['AD02AA', 'AD02AB', 'AD02AC']}]

一种方法是:(请参阅答案末尾的注释)

from itertools import groupby
from pprint import pprint

my_list = [
    "AD01",
    "AD01AA",
    "AD01AB",
    "AD01AC",
    "AD01AD",
    "AD02",
    "AD02AA",
    "AD02AB",
    "AD02AC",
]

res = []
for _, g in groupby(my_list, len):
    lst = list(g)
    if len(lst) == 1:
        res.append({"Legacy": lst[0], "rphy": []})
    else:
        res[-1]["rphy"].append(lst)

pprint(res)

输出:

[{'Legacy': 'AD01', 'rphy': [['AD01AA', 'AD01AB', 'AD01AC', 'AD01AD']]},
 {'Legacy': 'AD02', 'rphy': [['AD02AA', 'AD02AB', 'AD02AC']]}]

这假设您的数据始终以您想要的键开头(与下一个值相比具有最小名称的名称)。

基本上在每次迭代中,您都会检查 groupby 中创建的列表的长度。如果它是 1,这意味着它是你的钥匙,如果不是,它将把下一个项目添加到字典中。

注意:如果没有至少 2 个名称的长度大于两个键之间的键,则此代码将中断。