Извлечение списка из строки в Python - PullRequest
0 голосов
/ 04 июля 2018

Я пытаюсь работать с набором данных фильма Корнелла, чтобы создать чат-бота. Вот формат списка строк, из которого я хочу извлечь, сохраненный как conv_lines:

["u0 +++$+++ u2 +++$+++ m0 +++$+++ ['L194', 'L195', 'L196', 'L197']",
 "u0 +++$+++ u2 +++$+++ m0 +++$+++ ['L198', 'L199']",
 "u0 +++$+++ u2 +++$+++ m0 +++$+++ ['L200', 'L201', 'L202', 'L203']"] 

Я пытаюсь создать следующий список из приведенного выше списка строк, извлекая список внутри каждой строки.

[['L194', 'L195', 'L196', 'L197'],
 ['L198', 'L199'],
 ['L200', 'L201', 'L202', 'L203']]

Я нашел этот код, но не понимаю, как он работает. Кто-нибудь, пожалуйста, объясните.

convs = [ ]
for line in conv_lines[:-1]:
    _line = line.split(' +++$+++ ')[-1][1:-1].replace("'","").replace(" ","")
    convs.append(_line.split(','))

Я не понимаю, почему [: -1] использовалось в операторе for и после кода после разбиения.

Ответы [ 3 ]

0 голосов
/ 04 июля 2018
  • Использование re для поиска содержимого между []
  • Использование ast.literal_eval для получения списка объектов

Демо:

import re
import ast
data = ["u0 +++$+++ u2 +++$+++ m0 +++$+++ ['L194', 'L195', 'L196', 'L197']",
 "u0 +++$+++ u2 +++$+++ m0 +++$+++ ['L198', 'L199']",
 "u0 +++$+++ u2 +++$+++ m0 +++$+++ ['L200', 'L201', 'L202', 'L203']"]

res = []
for i in data:
    val = re.findall(r"\[.*?\]", i)[0]
    res.append(ast.literal_eval(val))
print(res)

Выход:

[['L194', 'L195', 'L196', 'L197'], ['L198', 'L199'], ['L200', 'L201', 'L202', 'L203']]
0 голосов
/ 04 июля 2018

Чтобы понять, в чем ваш вопрос, это помогает узнать контекст. К счастью, я точно знаю контекст, потому что я прошел тот же курс, что и вы. ;)

convs = []
for line in conv_lines[:-1]:
    _line = line.split(' +++$+++ ')[-1][1:-1].replace("'","").replace(" ","")
    convs.append(_line.split(','))

for items in some_list[:-1] обычно означает, что вы перебираете список до последнего элемента в этом списке и исключаете его.

Например:

l = [1,2,3,4]
for i in l[:-1]:
    print(i)
Out[ ]:
1
2
3

Теперь, что это значит для кода, который вы разместили. В операторе for вы захватываете все в строке, кроме последнего. Таким образом, последний элемент должен быть мусором бесполезным. Не верь мне на слово. Проверь это. Что print(conv_lines[-1]) показывает вам?

Теперь для другого использования [-1]. Попробуйте сначала разбить его, используя только одну строку из ваших необработанных данных.

line = "u0 +++$+++ u2 +++$+++ m0 +++$+++ ['L194', 'L195', 'L196', 'L197']"
convs = []
_line = line.split(' +++$+++ ')[-1] # notice I truncated after this.
convs.append(_line.split(','))

Что это возвращает?

convs
Out[ ]:
[["['L194'", " 'L195'", " 'L196'", " 'L197']"]]

А как теперь.

convs = []
_line = line.split(' +++$+++ ')[-1][1:-1] # truncated again, but after adding back a bit.
convs.append(_line.split(','))

А что это возвращает?

convs
Out[ ]:
[["'L194'", " 'L195'", " 'L196'", " 'L197'"]]

Продолжай.

convs = []
_line = line.split(' +++$+++ ')[-1][1:-1].replace("'","") # truncated less
convs.append(_line.split(','))

Возвращает:

convs
Out[ ]:
[['L194', ' L195', ' L196', ' L197']]

И наконец:

convs = []
_line = line.split(' +++$+++ ')[-1][1:-1].replace("'","").replace(" ","")
convs.append(_line.split(','))

Возвращает то, что вам нужно для остального кода, предоставленного ребятами из superdatascience:

convs
Out[ ]:
[['L194', 'L195', 'L196', 'L197']]

Имейте в виду, что этот пример работает только с одной строкой. С помощью цикла for вы будете заполнять список convs намного более чем одним списком из 4 цифр. Это помогает?

0 голосов
/ 04 июля 2018

Вы можете использовать ast.literal_eval и re:

import re, ast
d = ["u0 +++$+++ u2 +++$+++ m0 +++$+++ ['L194', 'L195', 'L196', 'L197']","u0 +++$+++ u2 +++$+++ m0 +++$+++ ['L198', 'L199']", "u0 +++$+++ u2 +++$+++ m0 +++$+++ ['L200', 'L201', 'L202', 'L203']"]
new_d = [ast.literal_eval(re.findall('\[[\w\W]+\]', i)[0]) for i in d]

Выход:

[['L194', 'L195', 'L196', 'L197'], ['L198', 'L199'], ['L200', 'L201', 'L202', 'L203']]
...