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)
我有以下内容:
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)