【问题标题】:Separate dictionary into multiple lists using values使用值将字典分成多个列表
【发布时间】:2020-04-23 16:36:29
【问题描述】:

我有一个用来填充字典的函数。该函数遍历 QGIS 中的两个图层,并返回图层相交的属性并将键和值分配给 dict,如下所示:

dict[id_code] = value

字典的内容:

{'CB000004657321': 'LT_07324_TRN1', 'CB000004657327': 'LT_07324_TRN1', 'CB000004132360': 'LT_07324_TRN2', 'CB000004132384': 'LT_07324_TRN2', 'CB000004133606': 'LT_07324_TRN2', 'CB000004133629': 'LT_07324_TRN2', 'CB000004131653': 'LT_07324_TRN2', 'CB000004130408': 'LT_07324_TRN2', 'CB000004132025': 'LT_07324_TRN2', 'CB000004131107': 'LT_07324_TRN2', 'CB000004130785': 'LT_07324_TRN2', 'CB000004132780': 'LT_07324_TRN2', 'CB000004130778': 'LT_07324_TRN2', 'CB000004132018': 'LT_07324_TRN2', 'CB000004658296': 'LT_07324_TRN1', 'CB000004657328': 'LT_07324_TRN1'}

该功能工作正常,字典包含预期的所有密钥对。在 dict 中大约有 15 个键值对。现在我正在用 2 个可能的值进行测试。我想做的是根据值(分成两个列表)分离我的字典 - 即 list_1 = ([key + vals]) where vals == 'type_a' / list_2 = ([key + vals]) where vals == 'type_b' 等

到目前为止我尝试过的是:

  1. 我在字典中使用 :s_vals = set(dict.values()) 获得了一组唯一值,我在下面的循环中使用了这些值。

    我使用的是 s_val 而不仅仅是硬编码的值,因为这些值可以在项目之间改变(因此我首先设置一个唯一值)

  2. 我创建了 2 个空列表:

    list_1 = []
    list_2 = []
    
  3. 然后我使用下面的函数来填充我的列表:

    def fn_ouput_list(liste, dict):
        for elem in s_vals:
            for key, value in dict.items():
                if dict[key][:] == elem:
                    liste.extend([key, value])
        return liste
    
    list_1 = fn_ouput_list(list_1, dict) 
    list_2 = fn_ouput_list(list_2, dict)
    

问题是我的函数产生了两个相同的列表,所有的键值对,我真的不明白为什么?

我试图将字典分成两个列表,但两个字典可能更好/更容易吗?

【问题讨论】:

  • 欢迎来到 SO!此示例不是诊断问题所必需的minimal reproducible example,但根据您所显示的,您使用相同的字典调用相同的函数,那么为什么输出应该不同?
  • @ggorlen 嗨,感谢您的回复。我正在尝试使用值将单个字典拆分为多个列表 - 因此所有值为“A”的键值对都在 list_1 中,所有值为“B”的键值对都在列表_2。就是这个想法,再次查看该功能,我怀疑它是否会起作用...您要我发布字典的内容吗?
  • 是的,请出示您开始使用的字典和预期的结果结构。谢谢。
  • @ggorlan 谢谢我已经添加了字典内容和其他一些 cmets

标签: python list dictionary


【解决方案1】:

如果我理解正确,您可以遍历 dict 并随时构建两个列表,

d = {'a': '000_TRN1', 'b': '000_TRN2'}

list1 = []
list2 = []
for k,v in d.items():
    if v[-1] == '1':   # if last letter of value is '1'
        list1.append((k,v))
    elif v[-1] == '2': # if last letter of value is '2'
        list2.append((k,v))

print(list1)
# [('a', '000_TRN1')]

print(list2)
# [('b', '000_TRN2')] 

或者,更简洁一点,但会做额外的工作,

list1 = [(k,v) for k,v in d.items() if v[-1]=='1']
list2 = [(k,v) for k,v in d.items() if v[-1]=='2']

编辑:根据 OP 的评论,考虑在 dict 中构建列表,以节省 if/else 语句,

d = {'CB000004132018': 'LT_07324_TRN2', 'CB000004658296': 'LT_07324_TRN1'}

z = {v[-4:]: [] for v in d.values()}
for k,v in d.items():
    z[v[-4:]].append((k,v))

z
# {'TRN1': [('CB000004658296', 'LT_07324_TRN1')],
#  'TRN2': [('CB000004132018', 'LT_07324_TRN2')]}

你可以随意拉出列表,或者做

alllists = [v for v in z.values()]

并获取列表列表。

【讨论】:

  • 嗨,谢谢,这将在这个例子中工作 - 但我不能在脚本中写入值(即在你的 for 循环中“if v[-1] == '1'”例如),因为我有其他字典,其中的值可以是任何值 - 这就是我使用 's_vals = set(dict.values())' 的原因 - 这会返回字典中的一组唯一值以及我开始的原因我的 for 循环带有 'for elem in s_vals:' 所以对于字典中的每个唯一值,我运行另一个循环以将 elem 与字典中的值进行比较并分配给一个列表 - 但它很乱并且不起作用:( - 我'稍后再试并更新我的帖子
  • 谢谢!我已经对其进行了一些修改以在我的功能中工作,并对其进行了测试,并且工作正常!干杯!
  • ..我也会投赞成票,但我还没有足够的代表...
猜你喜欢
  • 2011-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-23
  • 1970-01-01
  • 2020-04-23
相关资源
最近更新 更多