Python 按组映射列表中的值

Python mapping values in a list by group

我有以下内容:

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 可能是 ['cat','cat','cat','dog','dog','bird']

您可以先将映射创建为 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']

如果您不在意颜色顺序:

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]

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

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 列表。

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

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

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.

的其他答案

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

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)