Подтвердить что ты не робот

Разбор кортежа из строки?

Скажем, что у меня есть строка, которая имеет ту же форму, что и кортеж, например, "(1,2,3,4,5)". Какой самый простой способ превратить это в настоящий кортеж? Пример того, что я хочу сделать, это:

tup_string = "(1,2,3,4,5)"
tup = make_tuple(tup_string)

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

4b9b3361

Ответ 1

уже существует!

>>> from ast import literal_eval as make_tuple
>>> make_tuple("(1,2,3,4,5)")
(1, 2, 3, 4, 5)

Помните об угловом футляре:

>>> make_tuple("(1)")
1
>>> make_tuple("(1,)")
(1,)

Если ваш формат ввода отличается от Python здесь, вам нужно обрабатывать этот случай отдельно или использовать другой метод, например tuple(int(x) for x in tup_string[1:-1].split(',')).

Ответ 2

Вы можете анализировать свою строку без SyntaxError

def parse_tuple(string):
    try:
        s = eval(string)
        if type(s) == tuple:
            return s
        return
    except:
        return

Эта функция возвращает Tuple, если синтаксический анализ является успешным. В противном случае верните None.

print parse_tuple("('A', 'B', 'C')")

Ответ 3

Мы также можем разобрать его сами. Скажем, у нас есть кортеж, возвращаемый Python, как показано ниже:

((2, 'C/C++', 0, 'clang_cpp'), (3, 'Python相关', 0, 'python'))

Вот как мы это делаем

Сначала мы продолжаем читать символы в строке кортежа, но сохраняем последнюю позицию с запятой слева и количество точек с запятой, которые мы встречаем (мы можем называть ее левой точкой с запятой, как и для правой точки с запятой), всякий раз, когда мы встречаем правильную точку с запятой, мы делаем следующее:

  • Возьмем подстроку из последней точки с запятой в текущую правую точку с запятой. (В этой подстроки больше нет точек с запятой, мы просто разделим ее на array by ",". Пусть говорят, что новый массив M)
  • Затем мы добавляем M к нашему массиву результатов, который будет хранить все M.
  • В-третьих, удалите подстроку, взятую из исходной строки.   Наконец, делайте то же самое, что и шаг 1 до правого и левого   уровень с запятой достигает 0.

JavaScript-код выглядит следующим образом:

function parseTuple(t){
    var lc = "(";
    var rc = ")";
    var lc_level = 0;
    var rc_level = 0;
    var last_lc = 0;
    var last_rc = 0;
    var result = [];
    for(i=0;i<t.length;i++){
        if(t[i] == lc){
            lc_level++;
            last_lc = i;
        }else if(t[i] == rc){
            rc_level++;
            last_rc = i;
        }
        if(rc_level == 1){
            var substr = t.slice(last_lc+1,last_rc);
            var data = substr.split(",");
            result.push(data);
            lc_level--;
            rc_level--;
            i = 0;
            t = t.slice(0,last_lc) + t.substring(last_rc+1);
        }
        if(lc_level == rc_level && lc_level==0){
            break;
        }
    }
    return result;
}

Ответ 4

Я бы рекомендовал использовать literal_eval.

Если вам не нравится literal_eval или вы хотите иметь больше контроля над тем, что преобразуется, вы также можете разобрать строку, преобразовать значения и воссоздать кортеж.

Звучит сложнее, чем есть, на самом деле это однострочный:

eg = '(102,117,108)'
eg_tuple = map(int, eg.replace('(','').replace(')','').split(',')))

Это вызовет ValueError, если какой-либо элемент (строка) в кортеже не будет конвертирован в int, например, как '1.2' в строке: '(1.2, 3, 4)'.


То же самое можно сделать с помощью regex:

import re
eg = '(102,117,108)'
et_tuple = tuple(map(int, re.findall(r'[0-9]+', eg)))