Как я могу присоединиться к указанным c кортежам в моем списке - PullRequest
0 голосов
/ 13 апреля 2020

Мне нужно создать список кортежей, которые содержат состояние (SPACE, WRITE, SYMBOL, et c) и токен (, +, [A-Za-z0-9]*).

Мой ввод представляет собой строку токенов:

+ adfe3 + 212daeE

В настоящее время я использую этот оператор для преобразования моей входной строки в список кортежей, содержащих состояние и токен:

result = [(conversion_from_token_to_state(t),t) for t in stringOfTokens]

Что приводит к:

[('WRITE', '+'), ('SYMBOL', ' a '), (' SYMBOL ',' d '), (' SYMBOL ',' f '), (' SYMBOL ',' e '), (' SYMBOL ',' 3 '), (' SPACE ',' '), (' WRITE ',' + '), (' SYMBOL ',' 2 '), (' SYMBOL ',' 1 '), (' SYMBOL ',' 2 '), (' SYMBOL ',' d '), (' SYMBOL ',' a '), (' SYMBOL ',' e '), (' SYMBOL ',' E ')] *

Как можно уменьшить эти кратные последовательности ('SYMBOL', 'a') кортежей в один ('SYMBOL', 'adfe3')?

Полагаю, мне нужно добавить некоторую конструкцию if else в мое понимание списка, но я не могу понять, как заставить его обрабатывать только символы / числа и не говоря уже о других.

Itertools.groupby , кажется, ответ, но я не понимаю, как это может быть применено таким образом, что только последовательные кортежи SYMBOL объединяются в один. * 103 3 *

Справочная информация для вопроса: это (состояния, токены перехода) в машине состояний, и поэтому вполне возможно, что только некоторые токены (в данном случае SYMBOL) должны быть сгруппированы для перехода состояния, но несколько WRITE или SPACE могут возникать без необходимости группировки.

Ответы [ 2 ]

2 голосов
/ 13 апреля 2020

Вы были на правильном пути. Попробуйте это:

from operator import itemgetter
from itertools import groupby

tokens = [('WRITE', '+'), ('SYMBOL', 'a'), ('SYMBOL', 'd'), ('SYMBOL', 'f'), ('SYMBOL', 'e'), ('SYMBOL', '3'), ('SPACE', ' '), ('WRITE', '+'), ('SYMBOL', '2'), ('SYMBOL', '1'), ('SYMBOL', '2'), ('SYMBOL', 'd'), ('SYMBOL', 'a'), ('SYMBOL', 'e'), ('SYMBOL', 'E')]

simplified_token = [(k, ''.join(list(x[1] for x in g))) for k, g  in groupby(tokens, key=itemgetter(0))]

print(simplified_token)

Вывод:

[('WRITE', '+'), ('SYMBOL', 'adfe3'), ('SPACE', ' '), ('WRITE', '+'), ('SYMBOL', '212daeE')]

0 голосов
/ 13 апреля 2020

Вы можете сделать функцию ключа для itertools.groupby вывода нового экземпляра object, если первый элемент не SYMBOL, так что только элементы SYMBOL будут сгруппированы вместе, так как нет двух экземпляров object могут быть равны друг другу:

[next(g) if k else ('SYMBOL', ''.join(i for _, i in g))
    for k, g in groupby(stringOfTokens, key=lambda t: t[0] != 'SYMBOL' and object())]

Возвращает:

[('WRITE', '+'), ('SYMBOL', 'adfe3'), ('SPACE', ' '), ('WRITE', '+'), ('SYMBOL', '212daeE')]
...