#python #dictionary #split
#python #словарь #разделить
Вопрос:
У меня есть список словарей, и в каждом списке есть ключ, называемый text, со строковым значением. К каждому словарю я хочу добавить новый элемент, который называется first_word, который является разделением строки текста для получения кода.
Например, если у меня есть:
alist =[{'id':1, 'text':'Dogs are great'},
{'id':2, 'text':'Cats are great'},
'id':3, 'text':'Fish are smelly'}]
Я бы хотел добавить новое поле с именем first_word:
alist =[{'id':1, 'text':'Dogs are great', 'first_word':'Dogs'},
{'id':2, 'text':'Cats are great', 'first_word':'Cats'},
'id':3, 'text':'Fish are smelly', 'first_word':'Fish'}]
Код, который я использую для попытки этого, приведен ниже:
for ditem in alist:
ditem['first_word'] = ditem['text'].split()[0]
однако я получаю сообщение об ошибке:
Ошибка IndexError: индекс списка выходит за пределы диапазона
Как я могу это сделать?
Комментарии:
1. Есть ли какое-либо пустое строковое значение для
text
? Ошибка говорит о том, что результатомsplit
является пустой список, следовательноlist[0]
, вызываетIndexError
2. Могут ли в вашем списке быть dicts с пустым текстом?
3. После исправления опечатки в примере (
{
перед'id':3
) цикл у меня работает нормально. Возможно, в ваших фактических данных где-то есть пустая строка дляtext
.4. оберните
ditem['first_word'] = ditem['text'].split()[0]
вtry
—except IndexError
и добавьтеprint(ditem)
в except. Вы узнаете, когда увидите это.5. Это результат вашего скрипта (после исправления, предложенного Muru: [{‘text’: ‘Собаки замечательные’, ‘id’: 1, ‘first_word’: ‘Собаки’}, {‘text’: ‘Кошки замечательные’, ‘id’: 2, ‘first_word’: ‘Кошки’}, {‘text’: ‘Рыба вонючая’, ‘id’: 3, ‘first_word’: ‘Рыба’ }] работает так, как ожидалось
Ответ №1:
Передайте методу split
символ пустого пробела, например :
for ditem in alist:
ditem['first_word'] = ditem['text'].split(' ', 1)[0]
Используйте второй аргумент для .split()
, чтобы разрешить раннюю остановку разделения в случае, если ваши строки большие.
Ответ №2:
Вероятно, в вашем списке есть dicts, ‘text’ которых пуст.
Вы можете либо очистить свои данные, либо, если вы хотите игнорировать пустые тексты и добавить пустое ‘first_word’ в этом случае, вы могли бы сделать:
for ditem in alist:
ditem['first_word'] = ditem['text'].split()[0] if ditem['text'] else ''
Ответ №3:
Ваш код работает хорошо, если не считать опечатки. Вы пропустили {
перед третьим элементом.
Jupyter выдает это
File "<ipython-input-17-6aeaa3a052d5>", line 5
'id':3, 'text':'Fish are smelly'}]
^
SyntaxError: invalid syntax
Просто измените его
alist =[{'id':1, 'text':'Dogs are great'},
{'id':2, 'text':'Cats are great'},
{'id':3, 'text':'Fish are smelly'}]
for ditem in alist:
ditem['firstword']=ditem['text'].split()[0]
alist
Вывод:
[{'id': 1, 'text': 'Dogs are great', 'firstword': 'Dogs'},
{'id': 2, 'text': 'Cats are great', 'firstword': 'Cats'},
{'id': 3, 'text': 'Fish are smelly', 'firstword': 'Fish'}]
Комментарии:
1. В моем реальном коде этой проблемы нет, но я не могу заставить свой код работать.
Ответ №4:
У вас ошибка в вашем словаре. Посмотрите на строку 3, если в списке у вас отсутствует фигурная скобка.
Ответ №5:
alist =[{'id':1, 'text':'Dogs are great'}, {'id':2, 'text':'Cats are great'}, {'id':3, 'text':'Fish are smelly'}]
def append_kv(dd):
dd['first_word '] = ''
return dd
alist = [append_kv(dd) for dd in alist]
Ответ №6:
То, IndexError
что вы упомянули, должно происходить только при попытке получить доступ к элементу списка, который не существует. У вас есть ровно один доступ к списку (вывод списка из ditem['text'].split()
, и вы пытаетесь получить доступ к его первому элементу, поэтому этот список должен быть пустым. Это происходит именно тогда, когда ditem['text']
значение пусто, что дает нам быстрое решение: проверьте, пусто ли оно.
for ditem in alist:
t = ditem['text']
ditem['first_word'] = t.split()[0] if t else None
Ответ №7:
Отложив недостающую фигурную скобку, ваш код работает с отображаемыми вами входными данными.
Единственное, при каких обстоятельствах вы получите list index out of range
исключение, — это если text
значение пусто:
In [11]: for ditem in alist:
...: ditem['first_word'] = ditem['text'].split()[0]
...:
IndexError: list index out of range
Один из способов исправить это — явно обработать пустой текст:
In [12]: for ditem in alist:
...: ditem['first_word'] = ditem['text'].split()[0] if ditem['text'] else ''
...:
...: