Как разбить строку и получить желаемое значение? - PullRequest
0 голосов
/ 08 мая 2020

Посмотрите так, укажите позицию как строковый тип:

str1 = "0,0|2,5|...|"

Это ввод пользователя, каждая позиция разделена на "|", поэтому мы не знаем количество позиций. Мне нужно сохранить каждую позицию в определенных переменных pos1, pos2, ...., pos4....

Например:

pos1 = 0,0 pos2 = 2,5,..., pos4=...

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

Как я могу сделать это с меньшими затратами времени?

enter image description here

Ответы [ 3 ]

1 голос
/ 08 мая 2020

Вы можете создать словарь, в котором каждый ключ будет иметь значение pos (pos1, pos2, et c), а значение будет соответствовать объекту Pos.

Попробуйте следующее:

class Pos:
    # make sure you add x,y to your class constructor in order to be able to init it dynamically
    def __init__(self, x, y):
        self.x = x
        self.y = y

pos_mapping = {}
pos_list = str1.split("|") # pos_list = ["0,0", "2,5" ...]
for i,p in enumerate(pos_list):
    x,y = p.split(",") # split the position string by comma to extract x,y 
    pos_mapping[f"pos{i+1}"] = Pos(x,y)

Итак, если вы хотите получить pos2, просто выполните:

pos_mapping["pos2"]
0 голосов
/ 08 мая 2020

Во-первых, на скриншоте вы не указали ps2 = Pos(). Таким образом, исходный код в настоящее время работать не будет. И еще одно: объявите имя класса в PascalCase. Это python соглашение.

вы на самом деле задали 3 вопроса. Давайте войдем.

FYI: я предполагал, что все значения pos (x и y) будут целыми.

  1. Как обрабатывать входы неопределенного размера ( в данном случае str1)?

вы можете использовать string.split() встроенный метод python. Это выглядит так:

my_str = "Hi, I'm now making answer to your questions"
DELIMITER = " "
my_str.split(DELIMITER) # ['Hi,', "I'm", 'now', 'making', 'answer', 'to', 'your', 'questions']

В вашем случае каждая пара позиций будет разделена символом вертикальной линии (|).

my_str = "2,0|3,4|7,2|8,6|9,1"
delimiter = "|"
for (x,y) in my_str.split(delimiter):
    print(f'x is {x}, y is {y}')

# the output is:
# 2,0
# 3,4
# 7,2
# 8,6
# 9,1

Вам не о чем беспокоиться о размере пары, потому что метод split() разделит целевой фрагмент на каждую пару, если вы не указали maxsplit числа. Это необязательный параметр split() (python3 .8 официальные документы: https://docs.python.org/3/library/stdtypes.html#str .split )

После разделения вы можете снова разделить на каждую пару (например, «2, 0 ").

Как сохранить эти значения (в данном случае каждый экземпляр POS)?

Один из самых простых способов - использовать встроенный список python и его метод append().

storage = []
for num in range(0, 10):
    storage.append(num)
    print(storage)

# the output is :
# [0]
# [0, 1]
# [0, 1, 2]
# [0, 1, 2, 3]
# [0, 1, 2, 3, 4]
# [0, 1, 2, 3, 4, 5]
# [0, 1, 2, 3, 4, 5, 6]
# [0, 1, 2, 3, 4, 5, 6, 7]
# [0, 1, 2, 3, 4, 5, 6, 7, 8]
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 

Поскольку список python является динамическим c массивом, хранилище увеличивается на каждом append().

Короче говоря, вы можете использовать список python ' 'структура данных для хранения значений неизвестного размера. (Конечно, вы можете хранить экземпляры POS, хотя я показал только целочисленный регистр!)

Как обрезать временную сложность?

Не уверен в этом. Я думаю, что не будет критической разницы, если количество пар меньше 10k.

Но если размер больше, я могу использовать эти методы (и, вероятно, буду использовать c ++ вместо python):

# notice that this is pseudo code
storage = []

p = pos() 
x, y = 0, 0 # initialize
status = 0 # "what am I working for now?" (0 is for x, 1 is for y)
for character in str1:
    if character is number:
        if status == 0:
            x = 10*x + number(character)
        else: # status == 1
            y = 10*y + number(character)
    elif character is ",":
        p.x = x
        x = 0 # re-initialize
        status = 1 # "x is done"
    else: # status is "|"
        p.y = y
        y = 0 # re-initialize
        status = 0 # "y" is done"
        storage.append(p) # add new instance
        p = pos() # start another instance

приведенный выше код будет проверять каждый символ только один раз в течение всего выполнения. (Я думаю, что это очень cpp -стиль. Не так ли?) Таким образом, сложность времени будет O (n), где n - длина строки. Но будь осторожен! Я не проводил никаких тестов по этому поводу.

0 голосов
/ 08 мая 2020

Во-первых, нет причин иметь конструктор класса без параметров. Пусть он принимает одновременно x и y:

class Pos:
    def __init__(self, x, y):
        self.x = x
        self.y = y

Теперь вы можете разделить строку сначала по вертикальной черты, а затем по запятым. Примените int к каждому результирующему кортежу, чтобы преобразовать его элементы в числа. Наконец, создайте Pos из каждого кортежа:

positions = [Pos(*map(int, point.split(","))) 
          for point in str1.split("|")]
...