Как понять результат понимания списков вложенных списков при обратном порядке? - PullRequest
0 голосов
/ 27 ноября 2018

Я пытаюсь извлечь числа, смешанные в предложениях.Я делаю это, разбивая предложение на элементы списка, а затем перебираю каждый символ каждого элемента, чтобы найти числа.Например:

String = "is2 Thi1s T4est 3a"
LP = String.split() 
for e in LP:
    for i in e:
        if i in ('123456789'):
            result += i

Это может дать мне желаемый результат: ['2', '1', '4', '3'].Теперь я хочу написать это в списке понимания.После прочтения Понимание списка во вложенном списке? post Я понял, что правильный код должен быть:

[i for e in LP for i in e if i in ('123456789') ]

Мой оригинальный код для подхода к пониманию списка был неверным, но я пытаюсь обернуть голову вокруг полученного результата.

Мой оригинальный неверный код, который изменил порядок:

[i for i in e for e in LP if i in ('123456789') ]

В результате я получаю:

['3', '3', '3', '3']

Может ли кто-нибудь объяснить процесс, который приводит кэтот результат, пожалуйста?

Ответы [ 2 ]

0 голосов
/ 27 ноября 2018

Из вопроса, который вы задали в комментарии («как бы вы изменили порядок слов, используя список, который мы получили в качестве индекса?»):

Для этого мы можем использовать пользовательскую сортировку.(Обратите внимание, что регулярное выражение не требуется, но делает его немного проще. Используйте любой метод для извлечения числа из строки.)

import re

test_string = 'is2 Thi1s T4est 3a'
words = test_string.split()

words.sort(key=lambda s: int(re.search(r'\d+', s).group()))

print(words) # ['Thi1s', 'is2', '3a', 'T4est']

Чтобы удалить числа:

words = [re.sub(r'\d', '', w) for w in words]

Окончательный результат:

['This', 'is', 'a', 'Test']
0 голосов
/ 27 ноября 2018

Просто измените тот же процесс, который вы нашли в другом посте.Расположите циклы в одном и том же порядке:

for i in e:
    for e in LP:
        if i in ('123456789'):
            print(i)

Для кода необходимо заранее указать e и LP, поэтому результат, который вы видите , полностью зависит от другого кода, выполняемого перед вашим спискомпонимание .

Если предположить, что e было установлено на '3a' (последний элемент в LP из вашего кода, который выполнял полные циклы), то for i in e будет выполняться дважды, сначалас i, установленным на '3'.Затем мы получаем вложенный цикл, for e in LP, и, учитывая ваш вывод, LP имеет длину 4 элемента.Это повторяет 4 раза и каждую итерацию i == '3', поэтому тест if проходит и '3' добавляется к выводу.Следующая итерация for i in e: устанавливает i = 'a', внутренний цикл запускается 4 раза, но тест if не проходит.

Однако мы не можем знать наверняка потому что мы не знаем, какой код был запущен последним в вашей среде, для которого были установлены e и LP для начала.

Я не уверен, почему ваш исходный код использует str.split(), затем выполняет итерациинад всеми символами каждого слова.В любом случае, пробел никогда не пройдет через ваш фильтр if, поэтому вы можете просто зацикливаться непосредственно на полном значении String.Тест if можно заменить на тест str.isdigit() :

digits = [char for char in String if char.isdigit()]

или регулярное выражение :

digits = re.findall(r'\d', String)

и, наконец, если это головоломка с переупорядочением, вам нужно разделить строки на число (для упорядочения) и остаток (для объединения);отсортировать слова по извлеченному числу и извлечь остаток после сортировки:

# to sort on numbers, extract the digits and turn to an integer
sortkey = lambda w: int(re.search(r'\d+', w).group())
# 'is2' -> 2, 'Th1s1' -> 1, etc.

# sort the words by sort key
reordered = sorted(String.split(), key=sortkey)
# -> ['Thi1s', 'is2', '3a', 'T4est']

# replace digits in the words and join again
rejoined = ' '.join(re.sub(r'\d+', '', w) for w in reordered)
# -> 'This is a Test'
...