#python #list #mapping
Вопрос:
У меня есть следующее:
mylist = ['A','A','A','B','B','C']
colors = ['r','g','b','w','y']
Я хочу, чтобы все одинаковые элементы в моем списке получали один и тот же цвет с начала списка цветов, поэтому результат будет таким:
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… мой список мог быть [«кошка»,»кошка»,»кошка»,»собака»,»собака»,»птица»]
Комментарии:
1. Всегда ли » [«r»,»g»,»b»,»w», «y»] » сопоставляется с ABCDE или это зависит от
mylist
заданного ?
Ответ №1:
Вы можете сначала создать сопоставление как a 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']
Комментарии:
1. Спасибо! Никогда не пользовался этой функцией 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]
Комментарии:
1. dict поддерживает порядок с py3.7 , так полезно ли его продолжать использовать
OrderedDict
?2. @azro Я, должно быть, пропустил это, спасибо тебе за это. Тем не менее,
set(mylist)
не соблюдает порядок, поэтому я могу либо использоватьOrderedDict
для условностей, либо написать свою собственную функцию uniq (которая будет более производительной).sort
как и в вашем коде, зависит от того, что цвета уже отсортированы, что может иметь место, а может и не иметь.
Ответ №3:
Вы можете использовать счетчик, чтобы подсчитать, сколько раз значение появляется в вашем списке.
Затем используйте это сопоставление для заполнения списка результатов.
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
.
Ответ №4:
Для меня самым простым способом было бы:
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)
Ответ №5:
Я бы предложил вместо этого использовать словарь, чтобы сохранить сопоставление:
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
списка отдельно.