【问题标题】:Mapping items in one list to the items in another list将一个列表中的项目映射到另一个列表中的项目
【发布时间】:2021-11-23 08:43:50
【问题描述】:

我在 Python 中有两个列表,我正在尝试将一个的值映射到另一个。

列表 1(坐标):

['7,16', '71,84', '72,48', '36,52', '75,36', '52,28', '76,44', '11,69', '56,35',
 '15,21', '32,74', '88,32', '10,74', '61,34', '51,85', '10,75', '55,96',
 '94,12', '34,64', '71,59', '76,75', '25,16', '54,100', '62,1', '60,85',
 '16,32', '14,77', '40,78', '2,60', '71,4', '78,91', '100,98', '42,32', '37,49',
 '49,34', '3,5', '42,77', '39,60', '38,77', '49,40', '40,53', '57,48', '14,99',
 '66,67', '10,9', '97,3', '66,76', '86,68', '10,60', '8,87']

列表 2(索引):

[3, 2, 3, 3, 3, 3, 3, 1, 3, 3, 2, 3, 1, 3, 2, 1, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
 1, 2, 1, 3, 2, 2, 3, 3, 3, 3, 2, 2, 2, 3, 3, 3, 1, 2, 3, 3, 2, 2, 1, 1]

对于输出,我需要类似:

cluster_1: [x, y], [a,b]...

cluster_2: [c, d], [e, f]...

cluster_3: [g, h], [o, j]...

我尝试在字典中执行此操作,但我只能将其放入 for 循环中每个值的最后一个坐标中。它也总是从 0 开始输出键,我希望从 1 开始标记它们。

for i in range(len(patients)):
    # other stuff
    k = 3
    for b in range(k):
        if cluster == (k - b):
            dct['cluster_%s' % b] = patients[i]

哪个输出:

{'cluster_0': '97,3', 'cluster_1': '86,68', 'cluster_2': '8,87'}

我已尝试使用 dct['cluster_%s' % b].append(patients[i]),但在 cluster_0 上出现关键错误。任何帮助将不胜感激!

【问题讨论】:

    标签: python list dictionary for-loop


    【解决方案1】:

    您可以zip 您的索引和坐标,然后逐个循环遍历它们并根据索引填充字典。

    clusters = {}
    for idx, coord in zip(index, coords):
        if idx in clusters:
            clusters[idx].append(coord.split(','))
        else:
            clusters[idx] = [coord.split(',')]
    

    结果,其中clusters[i] 指的是第 i 个集群。

    >>> clusters
    {
        3: [['7', '16'], ['72', '48'], ['36', '52'], ['75', '36'], ['52', '28'], ['76', '44'], ['56', '35'], ['15', '21'], ['88', '32'], ['61', '34'], ['94', '12'], ['71', '59'], ['25', '16'], ['62', '1'], ['16', '32'], ['71', '4'], ['42', '32'], ['37', '49'], ['49', '34'], ['3', '5'], ['49', '40'], ['40', '53'], ['57', '48'], ['10', '9'], ['97', '3']],
        2: [['71', '84'], ['32', '74'], ['51', '85'], ['55', '96'], ['34', '64'], ['76', '75'], ['54', '100'], ['60', '85'], ['40', '78'], ['78', '91'], ['100', '98'], ['42', '77'], ['39', '60'], ['38', '77'], ['66', '67'], ['66', '76'], ['86', '68']],
        1: [['11', '69'], ['10', '74'], ['10', '75'], ['14', '77'], ['2', '60'], ['14', '99'], ['10', '60'], ['8', '87']]
    }
    

    【讨论】:

      【解决方案2】:

      您可以将defaultdictzip 一起使用:

      from collections import defaultdict
      
      clusters = defaultdict(list)
      for id, value in zip(cluster_indices, values):
          clusters[id].append(value.split(","))
      
      print(dict(clusters))  # {3: [['7', '16'], ['72', '48'], ...
      

      defaultdict 可以用dict(clusters) 转换为dict。但是,这可能没有必要,因为defaultdict 基本上扩展了dict


      注意:如果您需要int 值,则可以将value.split(",") 替换为[int(v) for v in value.split(",")]list(map(int, value.split(",")))。此时已经投射它们将为您节省以后的迭代。

      from collections import defaultdict
      
      clusters = defaultdict(list)
      for id, value in zip(cluster_indices, values):
          clusters[id].append([int(v) for v in value.split(",")])
      
      print(dict(clusters))  # {3: [[7, 16], [72, 48], ...
      

      group-by 行为提取到函数 groupby(使用 lambda function 以允许任何类型的转换),以便可以重复使用:

      from collections import defaultdict
      
      def groupby(indices, values, map_fn):
          grouped = defaultdict(list)
          for id, value in zip(indices, values):
              grouped[id].append(map_fn(id, value))
          return dict(grouped)
      
      clusters = groupby(cluster_indices, values, lambda _, value: value.split(","))
      
      print(clusters)  # {3: [['7', '16'], ['72', '48'], ...
      

      这里只是使用itertools.groupby的另一种方式:

      from itertools import groupby
      from operator import itemgetter
      
      data = sorted(zip(cluster_indices, values), key=itemgetter(0))
      grouped = groupby(data, key=itemgetter(0))
      clusters = {
          cluster: [value[1].split(",") for value in list(values)] 
          for cluster, values in grouped
      }
      
      print(clusters)  # {3: [['7', '16'], ['72', '48'], ...
      

      但是,我会使用上面的defaultdict 方法或Cory Kramer's answer,因为它更简单且更易于阅读(因此更可取)!

      【讨论】:

        猜你喜欢
        • 2014-07-21
        • 2017-09-28
        • 2021-03-17
        • 2021-12-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多