#python #list #indexing #eval #abstract-syntax-tree
Вопрос:
Я пытаюсь оценить некоторые выражения Python, такие как [1, 2, 3][1]
. Я не могу использовать eval('[1, 2, 3][1]')
, потому что каждый раз, когда я это делаю, котенок может умереть. Более безопасный способ-использовать ast.literal_eval('[1, 2, 3][1]')
, однако он вызывает ошибку значения:
ValueError: malformed node or string ...
Что можно сделать для того, чтобы это сработало? Заранее спасибо.
Комментарии:
1. Когда вы говорите «некоторые выражения Python, такие как [1, 2, 3][1]», что это включает в себя? Если это конкретно «литерал списка, за которым следует индекс в квадратных скобках», то вы можете разбить его на части, оценить их с помощью literal_eval, а затем объединить их в своей собственной логике. Если это более общее, чем это, пожалуйста, опишите.
2. Да, это литерал списка, за которым следует индекс в квадратных скобках, команда, которая работает с использованием
eval([1, 2, 3][1])
. Как я могу разбить его на части?
Ответ №1:
Возможно, есть какой-то лучший способ, но если формат такой, как вы описываете (литерал списка, за которым следует литерал индекса в квадратных скобках), то вы можете разделить его на части, оценить их по отдельности, а затем объединить их в своей логике.
import re from ast import literal_eval string = '[1, 2, 3][1]' m = re.match(r'^([. ])[(. )]
Комментарии:
1. А, понял. Это похоже на попытку разработать свой собственный способ компиляции этого кода. Надеюсь, в будущих версиях Python будут лучшие варианты, я надеюсь.
Ответ №2:
Если это так же просто, как выбрать целое число из списка, вы можете проанализировать его самостоятельно.
s = "[1, 12, 30][-1]" def foo(s): arr = [] curr = "" for c in s: if c.isdigit() or c in ["-"]: curr = c elif c == "," or c == "]": arr.append(int(curr)) curr = "" lst, ind = arr[:-1], arr[-1] return lst[ind] foo(s) # 30
Или, может быть,
arr, ind = ( s.replace("][", ";").replace("[", "").replace("]", "").replace(" ", "").split(";") ) int(arr.split(",")[int(ind)])
Комментарии:
1. Это тоже вариант, но, похоже, для этой довольно простой задачи потребуется много тяжелой работы.
Ответ №3:
Вы можете безопасно создавать AST с помощью входного сигнала, используя compile
встроенный. Но вы не можете безопасно оценить AST. Поэтому вам придется самому пройти AST, собирая целые числа и составляя из них список. Если выражение так просто, как вы говорите, это не составит труда.
, string) mylist = literal_eval(m.group(1)) index = literal_eval(m.group(2)) value = mylist[index] # gives value 2
Комментарии:
1. А, понял. Это похоже на попытку разработать свой собственный способ компиляции этого кода. Надеюсь, в будущих версиях Python будут лучшие варианты, я надеюсь.
Ответ №2:
Если это так же просто, как выбрать целое число из списка, вы можете проанализировать его самостоятельно.
Или, может быть,
Комментарии:
1. Это тоже вариант, но, похоже, для этой довольно простой задачи потребуется много тяжелой работы.
Ответ №3:
Вы можете безопасно создавать AST с помощью входного сигнала, используя compile
встроенный. Но вы не можете безопасно оценить AST. Поэтому вам придется самому пройти AST, собирая целые числа и составляя из них список. Если выражение так просто, как вы говорите, это не составит труда.