Я пытаюсь разобрать строку и заполнить массив конкретной информацией, содержащейся в строке, но у меня неожиданное поведение.

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

Рассмотрим строку: 'BEST POSITION:P(0) = 1.124 P(1) = 2.345 P(2) = 3.145 P(3) = 4.354'

Следующий код должен создать список: [1.124, 2.345, 3.145, 4.354]

inputs_best = np.zeros(4)
string_in = 'BEST POSITION:P(0) = 1.124 P(1) = 2.345 P(2) = 3.145 P(3) = 4.354'

best_sols_clean = ''
for item in string_in:
    best_sols_clean += item

best_sols_clean = re.sub('[ \t]', '', best_sols_clean)

count = 0
while best_sols_clean.find('P(') is not -1:
    line_index = best_sols_clean.find('P(')
    try:
        inputs_best[count] = float(best_sols_clean[line_index+5:line_index+10])
        best_sols_clean = best_sols_clean[line_index+10:-1]
        count += 1
    except ValueError:
        inputs_best[count] = float(best_sols_clean[line_index+5:line_index+6])
        best_sols_clean = best_sols_clean[line_index+6:-1]
        count += 1

print(inputs_best)

Результат этого сценария:

[1.124 2.345 3.145 4. ]

Для этой строки это работает, за исключением последней записи в списке, которая обрезана слишком маленькими цифрами.

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

string_in = 'BEST POSITION:P(0) = 1 P(1) = 2.345 P(2) = 3.145 P(3) = 4'

Что приводит к ошибке.

Я полагаю, что проблема заключается в строке best_sols_clean = best_sols_clean[line_index+10:-1], которая по какой-то причине отбрасывает завершающие цифры строки, даже если я делаю нарезки до последнего элемента строки.

Для строки string_in = 'BEST POSITION:P(0) = 1 P(1) = 2.345 P(2) = 3.145 P(3) = 4' программа завершает работу с ошибкой

Traceback (most recent call last):
  File "test.py", line 17, in <module>
    inputs_best[count] = float(best_sols_clean[line_index+5:line_index+10])
ValueError: could not convert string to float: 

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test.py", line 21, in <module>
    inputs_best[count] = float(best_sols_clean[line_index+5:line_index+6])
ValueError: could not convert string to float:

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

0
Mike 2 Июл 2019 в 00:04

3 ответа

Лучший ответ

Вы пытаетесь жестко закодировать крошечные кусочки, что делает вещи крайне неэффективными, уязвимыми и трудными для отладки. Возможно, у вас есть проблема с вашими индексами, но, возможно, не стоит даже углубляться. Почему бы вам просто не разбить вашу строку на пробел и попытаться записать все строки, выглядящие как числа, в список? Вроде как:

string_in = 'BEST POSITION:P(0) = 1.124 P(1) = 2.345 P(2) = 3.145 P(3) = 4.354'
numbers = []
for x in string_in.split(' '):
    # Append float-able strings into your list
    try: numbers.append(float(x))
    # Pass only on the ValueErrors, do not use bare except. Any other error should break the code by design
    except ValueError: pass
# Produces: [1.124, 2.345, 3.145, 4.354]

Если вы введете string_in = 'BEST POSITION:P(0) = 1 P(1) = 2.345 P(2) = 3.145 P(3) = 4', это вернет [1.0, 2.345, 3.145, 4.0]. Это хорошо для ваших целей?

2
FatihAkici 1 Июл 2019 в 21:19

Это выведет все числа в строке, которые не находятся в скобках:

import re
re.findall('[^(]([\d.]+)', string_in)

< Сильный > Пример:

import re

string_in = 'BEST POSITION:P(0) = 1.124 P(1) = 2.345 P(2) = 3.145 P(3) = 4.354'
print(re.findall('[^(]([\d.]+)', string_in))
# ['1.124', '2.345', '3.145', '4.354']

string_in = 'BEST POSITION:P(0) = 1 P(1) = 2.345 P(2) = 3.145 P(3) = 4'
print(re.findall('[^(]([\d.]+)', string_in))
# ['1', '2.345', '3.145', '4']
1
Rick Hitchcock 1 Июл 2019 в 21:38

Похоже, ваша проблема с этой линией

 best_sols_clean = best_sols_clean[line_index+10:-1]

Каждый раз, когда вы проходите цикл, вы убираете один символ из конца строки. Попробуйте изменить это на это:

 best_sols_clean = best_sols_clean[line_index+10:]
1
MBA Coder 1 Июл 2019 в 21:28