Мне нужно удалить список слов из значений определенного ключа в моем списке словарей.
Вот пример того, как выглядят мои данные:
words = ['cloves', 'packed']
data = [{'title': 'Simple Enchiladas Verdes',
'prep_time': '15 min',
'cook_time': '30 min',
'ingredients': ['chicken breast', 'tomato sauce', 'garlic cloves', 'fresh packed cilantro']
'instructions': ['some text...'],
'category': 'dessert',
'cuisine': 'thai',
'article': ['some text...']
},
{...}, {...}]
Желаемый результат:
data = [{'title': 'Simple Enchiladas Verdes',
'prep_time': '15 min',
'cook_time': '30 min',
'ingredients': ['chicken breast', 'tomato sauce', 'garlic', 'fresh cilantro']
},
{...}, {...}]
Пробовал разные коды:
remove = '|'.join(words)
regex = re.compile(r'\b('+remove+r')\b', flags=re.IGNORECASE)
for dct in data:
dct['ingredients']= list(filter(lambda x: regex.sub('', x), dct['ingredients']))
Но это возвращает следующую ошибку: TypeError: sub() отсутствует 1 обязательный позиционный аргумент: 'string'
Другие коды, которые я пробовал:
for dct in data:
dct['ingredients']= list(filter(lambda x: x != words, dct['ingredients']))
for dct in data:
dct['ingredients']=[[el for el in string if el in words ] for string in dct['ingredients']]
for dct in data:
for string in dct['ingredients']:
dct['ingredients'] = list(filter(lambda x: x not in words, dct['ingredients']))
Но ни один из них не решает мою проблему.
Почему не list
понимание с dict
ионарным пониманием:
data = [{k:([' '.join([s for s in x.split() if s not in words]) for x in v] if k == 'ingredients' else v) for k, v in i.items()} for i in data]
@annag Собственно, почему? это единственное, что можно заменить, так как перебор строк даст один символ, а значения списка больше
@ U9-Forward, потому что у меня есть другие ключи в словаре (здесь не отображаются). Я изменю пример данных.
@annag Отредактировал мой ответ, пожалуйста, примите его, если он работает :-)
@ U9-Forward код работает, но, к сожалению, ничего не меняет в моих данных
В вашем подходе re.sub
вы должны использовать map
, а не filter
(вы не отфильтровываете отдельные слова, а заменяете всю строку результатом re.sub
)
for dct in data:
dct['ingredients']= list(map(lambda x: regex.sub('', x), dct['ingredients']))
Или, возможно, более читаемо, как понимание списка:
dct['ingredients'] = [regex.sub("", x) for x in dct['ingredients']]
Однако оба оставят лишние пробелы. Если слова всегда разделяются пробелом, вы можете просто использовать split
и join
(быстрее, если words
является set
):
for dct in data:
dct['ingredients'] = [' '.join(w for w in string.split() if w not in words)
for string in dct['ingredients']]
words = ['cloves', 'packed']
data = [{'title': 'Simple Enchiladas Verdes',
'prep_time': '15 min',
'cook_time': '30 min',
'ingredients': ['chicken breast', 'tomato sauce', 'garlic cloves', 'fresh packed cilantro']}
]
for i in data:
word = ' @! '.join(i['ingredients'])
for k in words:
word = word.replace(k,'').strip()
i['ingredients']=[i.strip() for i in word.split('@!')]
выход
[{'title': 'Simple Enchiladas Verdes',
'prep_time': '15 min',
'cook_time': '30 min',
'ingredients': ['chicken breast',
'tomato sauce',
'garlic',
'fresh cilantro']}]
words = ['cloves', 'packed']
data = [{'title': 'Simple Enchiladas Verdes',
'prep_time': '15 min',
'cook_time': '30 min',
'ingredients': ['chicken breast', 'tomato sauce', 'garlic cloves', 'fresh packed cilantro']
},
{'title': 'Simple Enchiladas Verdes11',
'prep_time': '15 min11',
'cook_time': '30 min11',
'ingredients': ['chicken breast1', '1tomato sauce', '1garlic cloves', '1fresh packed cilantro']}
]
n = []
for d in data:
for item in d['ingredients']:
for word in words:
item = item.replace(word, '')
n.append(item)
d['ingredients'] = n
print (d)
выход:
{'title': 'Simple Enchiladas Verdes11', 'prep_time': '15 min11', 'cook_time': '30 min11', 'ingredients': ['chicken breast', 'tomato sauce', 'garlic ', 'fresh cilantro', 'chicken breast1', '1tomato sauce', '1garlic ', '1fresh cilantro']}
Но это заменит слова во всех моих ключах, а не только в ключе ['ингредиенты'], верно?