PostgreSQL允许在表达式上创建索引,例如CREATE INDEX ON films ((lower(title)))
.它还具有pg_get_expr()
信息功能,可将表达式的内部格式转换为文本,即lower(title)
在前一个示例中.这些表达式有时会非常毛茸茸.以下是一些示例(在Python中):
sample_exprs = [
'lower(c2)',
'lower(c2), lower(c3)',
"btrim(c3, 'x'::text), lower(c2)",
"date_part('month'::text, dt), date_part('day'::text, dt)",
'"substring"(c2, "position"(c2, \'_begin\'::text)), "substring"(c2, "position"(c2, \'_end\'::text))',
"(((c2)::text || ', '::text) || c3), ((c3 || ' '::text) || (c2)::text)",
'f1(f2(arga, f3()), arg1), f4(arg2, f5(argb, argc)), f6(arg3)']
Run Code Online (Sandbox Code Playgroud)
最后一项不是来自Postgres,而只是我的代码应该处理的一个极端例子.
我编写了一个Python函数来将文本列表拆分为组件表达式.例如,最后一项分为:
f1(f2(arga, f3()), arg1)
f4(arg2, f5(argb, argc))
f6(arg3)
Run Code Online (Sandbox Code Playgroud)
我尝试用str
类似的方法find()
和count()
和也被认为是正则表达式,但最后我写了一个功能,就是我会用C写的(主要是计数打开和关闭括号寻找到打破文本).这是功能:
def split_exprs(idx_exprs):
keyexprs = []
nopen = nclose = beg = curr = 0
for c in idx_exprs:
curr += 1
if c == '(':
nopen += 1
elif c == ')':
nclose += 1
if nopen > 0 and nopen == nclose:
if idx_exprs[beg] == ',':
beg += 1
if idx_exprs[beg] == ' ':
beg += 1
keyexprs.append(idx_exprs[beg:curr])
beg = curr
nopen = nclose = 0
return keyexprs
Run Code Online (Sandbox Code Playgroud)
问题是,是否有更多的Pythonic或优雅的方式来做到这一点或使用正则表达式来解决这个问题.
如果你想让它变得更加Python化,我能想到的唯一方法就是可读性。
此外,我通过计算堆栈来避免一个分支和一个变量。我能给出的唯一Pythonic建议是在函数中使用“index”变量enumerate(...)
。如在
for i, j in enumerate(<iterable>)
这将创建一个变量 ,i
它将等于当前循环编号,其中j
将是预期的迭代变量。
def split_fns(fns):
paren_stack_level = 0
last_pos = 0
output = []
for curr_pos, curr_char in enumerate(fns):
if curr_char == "(":
paren_stack_level += 1
elif curr_char == ")":
paren_stack_level -= 1
if not paren_stack_level:
output.append( fns[last_pos:curr_pos+1].lstrip(" ,") )
last_pos = curr_pos+1
return output
for i in sample_exprs:
print(split_fns(i))
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
163 次 |
最近记录: |