Пролог синглтон-переменных в Python
Я работаю над небольшим набором скриптов на Python, и я пришел к этому:
line = "a b c d e f g"
a, b, c, d, e, f, g = line.split()
Я вполне осознаю тот факт, что это решения, принимаемые во время реализации, но Python не должен (или не делает) предлагать что-то вроде:
_, _, var_needed, _, _, another_var_needed, _ = line.split()
а также Пролог предлагает, чтобы исключить знаменитый singleton variables
,
Я не уверен, но не избежит ли это ненужного распределения? Или создание ссылок на результат split
звонок не засчитывается как накладные расходы?
РЕДАКТИРОВАТЬ:
Извините, моя точка зрения такова: в Прологе, насколько мне известно, в выражении вроде:
test(L, N) :-
test(L, 0, N).
test([], N, N).
test([_|T], M, N) :-
V is M + 1,
test(T, V, N).
Переменная, представленная _
недоступен, для чего я предполагаю ссылку на значение, которое существует в списке [_|T]
даже не создан.
Но в Python, если я использую _
Я могу использовать последнее значение, присвоенное _
, а также, я полагаю, присваивание происходит для каждой из переменных _
- что можно считать накладными расходами.
Мой вопрос здесь, если не должно быть (или если есть) синтаксис, чтобы избежать таких ненужных атрибутов.
3 ответа
_
является совершенно допустимым именем переменной, и да, вы можете использовать переменную несколько раз в операции распаковки, так что написанное вами будет работать. _
будет заканчиваться последним значением, назначенным в строке. Некоторые программисты Python используют его таким образом.
_
используется в специальных целях некоторыми интерактивными оболочками Python, что может запутать некоторых читателей, поэтому некоторые программисты не используют его по этой причине.
Там нет никакого способа избежать выделения с str.split()
: он всегда разделяет всю строку, и результирующие строки всегда выделяются. Просто в этом случае некоторые из них живут не очень долго. Но опять же, кто это делает?
Вы можете избежать некоторых распределений, скажем, re.finditer()
:
import re
fi = re.finditer(r"\S+", line)
next(fi)
next(fi)
var_needed = next(fi).group()
next(fi)
next(fi)
another_var_needed = next(fi).group()
# we don't care about the last match so we don't ask for it
Но next()
возвращает Match
объект и поэтому он будет выделен (и немедленно отброшен, так как мы нигде его не сохраняем). Таким образом, вы действительно только сохраните окончательное распределение. Если ваши строки длинные, тот факт, что вы получаете Match
Я думаю, что объект, а не строка, может сэкономить память и даже время; Я думаю, что совпадающая строка не будет вырезана из исходной строки, пока вы не попросите ее. Вы можете профилировать это, чтобы быть уверенным.
Вы можете даже обобщить вышеприведенное в функцию, которая возвращает только нужные токены из строки:
import re
def get_tokens(text, *toknums):
toknums = set(toknums)
maxtok = max(toknums)
for i, m in enumerate(re.finditer(r"\S", text)):
if i in toknums:
yield m.group()
elif i > maxtok:
break
var1, var2 = get_tokens("a b c d e f g", 2, 5)
Но это все еще не совсем красиво.
По факту, _
является допустимым идентификатором в Python, и люди часто используют его для принятия значения, которое больше не понадобится, поэтому ваш код уже великолепен для Python.
В Python нет синтаксиса, который точно соответствует _
в прологе. Когда вы используете _
в Python это реальная переменная, которая действительно содержит ссылку на значение.
Тем не менее, существует много, много объектов, выделяемых и освобождаемых при запуске программы на Python. Даже если бы вы могли контролировать несколько таких мест, как вы показали, это просто капля, и это не повлияет на использование ресурсов вашей программы в достаточной степени.
Насколько синтаксис идет
_, _, var_needed, _, _, another_var_needed, _ = line.split()
это действительный питон. Я бы сказал, что это даже идиоматично, хотя и немного необычно.