Кортеж приведения Python[int, int]

#python #parsing #tuples

#python #синтаксический анализ #Кортежи

Вопрос:

У меня есть строка "1,2" , которую я пытаюсь проанализировать (1, 2) без простого разделения на основе , . Я интуитивно думал о чем-то вроде:

 from typing import Tuple
t = Tuple[int, int]("1,2")
 

Это, очевидно, не работает, но кажется логичным привести определенный тип кортежа (int, int) к строке для синтаксического анализа. Мысли?

Комментарии:

1. В дополнение к приведенному ниже ответу я укажу, что python не поддерживает «приведение» в том смысле, который вы, кажется, имеете в виду (т. Е. Приведение C lang). Да, вы можете делать что-то вроде l = [1, 2]; t = tuple(l) , но это не «приведение». Вы вызываете конструктор, который, оказывается, знает, как преобразовать список в кортеж.

Ответ №1:

typing Модуль предназначен для совершенно другого (подсказка типа). Насколько я знаю, для этого ничего не встроено. Вам нужно вручную проанализировать или eval это.

Разбор вручную достаточно прост, просто разделите , и преобразуйте каждый элемент в int :

 your_string = "1,2"
tuple(int(i) for i in your_string.split(","))
 

eval это позволяет проникать другим типам данных, но является более «автоматическим» (используется ast.literal_eval по соображениям безопасности):

 import ast

your_string = "1,2"
ast.literal_eval(your_string)
 

Комментарии:

1. Да, я думаю, что разделение строки — это правильный путь. Я надеялся, что смогу каким-то образом выполнить приведение, поскольку это будет довольно чистый код.

Ответ №2:

то, что Tomothy32 упомянул о разборе вручную на основе разделения по запятой, является правильным. Вы также можете использовать map для приведенного выше, как показано ниже —

 your_input = "1,2"
your_tuple = tuple(map(int, your_input.split(',')))
 

Ответ №3:

Для простого ввода, такого как "1,2" разделение на "," , это самое простое решение.

Если ввод более сложный — возможно, он содержит пробелы или существует много возможных разделителей — вы могли бы написать генератор, который выдает целые числа:

 >>> data = '18 ,15 ,18,15x,19,14,20,12,13,17'
>>> def interator(data):
...     digits = []
...     for c in data:
...         if c.isdigit():
...             digits.append(c)
...         else:
...             if digits:
...                 yield int(''.join(digits))
...                 del digits[:]
...     if digits:
...         yield int(''.join(digits))
... 
>>> tuple(interator(data))
(18, 15, 18, 15, 19, 14, 20, 12, 13, 17)
 

Как это часто бывает, есть однострочник itertools, который делает то же самое:

 >>> tuple(int(''.join(s)) for _, s in 
...       filter(lambda x: x[0], itertools.groupby(data, str.isdigit)))
(18, 15, 18, 15, 19, 14, 20, 12, 13, 17)
 

Но регулярное выражение было бы кратким и читаемым:

 >>> tuple(int(x.group(0)) for x in re.finditer(r'd ', data))
(18, 15, 18, 15, 19, 14, 20, 12, 13, 17)