Как разделить строковое значение словаря в списке словарей, чтобы добавить новый элемент словаря?

#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 ''
    ...:
    ...: