【问题标题】:Python mapping values in a list by groupPython按组映射列表中的值
【发布时间】:2021-07-02 02:18:39
【问题描述】:

我有以下几点:

mylist = ['A','A','A','B','B','C']

colors = ['r','g','b','w','y']

我希望 mylist 中所有相同的元素从颜色列表的开头获得相同的颜色,所以结果会是这样的:

result = ['r','r','r','g','g','b']

颜色 w 和 y 将被忽略。似乎无法使映射正常工作。

我试过了:

result = [[y for y in colors if set(mylist) == x] for x in mylist]

编辑:为了更清楚,['r','g','b','w','y'] 并不总是需要映射到 ABCDEF... mylist 可能是 [ '猫','猫','猫','狗','狗','鸟']

【问题讨论】:

  • `['r','g','b','w','y']` 是否总是被映射到 ABCDE 或者它取决于给定的mylist

标签: python list mapping


【解决方案1】:

您可以先将映射创建为dict,然后使用它来获取结果

mylist = ['A', 'A', 'A', 'B', 'B', 'C']
colors = ['r', 'g', 'b', 'w', 'y']

mapping = dict(zip(
    sorted(set(mylist)),
    colors
))
print(mapping)  # {'A': 'r', 'B': 'g', 'C': 'b'}

result = [mapping[l] for l in mylist]
print(result)  # ['r', 'r', 'r', 'g', 'g', 'b']

【讨论】:

  • 谢谢!没用过这个zip功能,学到了新东西:)
【解决方案2】:

如果你不关心颜色的顺序:

color_map = dict(zip(set(mylist), colors))
result = [color_map[item] for item in mylist]

如果你关心颜色的顺序:

from collections import OrderedDict

color_map = OrderedDict(zip(OrderedDict((item, True) for item in mylist), colors))
result = [color_map[item] for item in mylist]

【讨论】:

  • dict 自 py3.7 以来一直保持秩序,所以继续使用 OrderedDict 有用吗?
  • @azro 我一定错过了,谢谢。但是,set(mylist) 不保持顺序,所以我可以使用OrderedDict 方便或编写我自己的 uniq 函数(这会更高效)。 sort 在您的代码中依赖于已经排序的颜色,这可能会也可能不会。
【解决方案3】:

我建议改用字典来保留映射:

result = []
color_map = {}
idx = 0
for elt in mylist:
    if elt not in color_map.keys():
        color_map[elt] = colors[idx]
        idx += 1
    result.append(color_map[elt])

这也避免了单独迭代 colors 列表。

【讨论】:

    【解决方案4】:

    您可以使用 Counter 来计算某个值在列表中出现的次数。

    然后使用该映射来填充您的结果列表。

    from collections import Counter
    
    mylist = ['A','A','A','B','B','C']
    colors = ['r','g','b','w','y']
    result = []
    for idx, (_,v) in enumerate( Counter(mylist).items() ):
        result.extend( colors[idx] * v )
    print(result)
    

    输出:

    ['r', 'r', 'r', 'g', 'g', 'b']
    

    注意:需要 Python > 3.7,否则无法保证 dict 的顺序 - 这也适用于此处依赖 dict 的其他答案。

    【讨论】:

      【解决方案5】:

      对我来说最简单的方法是:

      mylist = ['A', 'A', 'A', 'B', 'B', 'C']
      colors = ['r', 'g', 'b', 'w', 'y']
      result = []
      
      for i, item in enumerate(sorted(set(mylist))):  # sets doesn't maintain the order, so its sorted alphabetically
          result.extend(colors[i] * mylist.count(item))
      
      print(result)
      

      【讨论】:

        猜你喜欢
        • 2022-01-26
        • 1970-01-01
        • 1970-01-01
        • 2022-11-10
        • 1970-01-01
        • 2011-04-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多