给定“前导空格分隔的元组字符串”,还原成合法的python元组tuple对象。
(笔记模板由python脚本于2023年12月29日 19:29:03创建,本篇笔记适合熟悉Python元组tuple的coder翻阅)
Python 官网:https://www.python.org/
Free:大咖免费“圣经”教程《 python 完全自学教程》,不仅仅是基础那么简单……
地址:https://lqpybook.readthedocs.io/
自学并不是什么神秘的东西,一个人一辈子自学的时间总是比在学校学习的时间长,没有老师的时候总是比有老师的时候多。
—— 华罗庚
本文质量分:
CSDN质量分查询入口:http://www.csdn.net/qc
本题目关键点在于,将另类的“元组”输入字符串,搞成它在python中的样子!我是想得黔驴技穷的时候,才构造好“算法”的。代码的调试,也花了我不少时光。(截屏图片后面是用题目中的两个样例对我“造”的“str to tuple”函数reTuple的试炼效果。)
本来打算直接用eval函数来把题目给出的“元组”转换成python对象,奈何题目刁钻的把元组的第一个元素包括元组关键字圆括号都全部加上了前导空格,eval也对它望洋“符”叹,无能为力。
设想多种“解决方案”未果,我决定从tuple对象在python中的样貌入手,借助python现在最是推崇的“插值字符串格式化”语法糖来“还原”元组本来面目。本以为顺风顺水很好搞,结果也是满路荆棘,迷雾重重。最后在“复杂”if语句的助攻下,完成了tuple相貌字符串的“还原”,再通过eval的打扮,才得以回复它的先前模样。
至此,下标索引引用及引用溢出的处理,就一马平川了。当eval抛出的异常信时,拦截并返回“ERROR”字符串就好。
如有必要,继续浏览后面内容,您且给点耐心听我一一拆解
谢谢题主给指正,我才得以在整理成学习笔记时修正。
单行匿名函数tupleToStr
tupleToStr = lambda x: x if type(x) != tuple else f"( {' '.join(map(str, x))} )" # 如果是tuple,则搞成题目样例输入那样的“元组”。
#input(tupleToStr((5, 6, 7))) # 函数试炼语句。
还原元组字符串成tuple样貌:我用元组在python中的字符串表现形式入手“还原”的,用if语句添加应有的半角逗号。
最初写法
if lis[i].isdigit() and (lis[i-1].isdigit() or lis[i-1] == ')') or (lis[i] == '(' and lis[i-1].isdigit()) or (lis[i] == '(' and lis[-1] == ')'): # 饶舌复杂,差点把我自己都绕晕。
简单优化
if lis[i].isdigit() and (lis[i-1].isdigit() or lis[i-1] == ')') or lis[i] == '(' and (lis[i-1].isdigit() or lis[-1] == ')'): # 条理稍微清晰,两个嵌套if。
升级蜕变
if lis[i].isdigit() and lis[i-1] != '(' or lis[i] == '(' and lis[i-1] != '(': # 两个并列条件的复合条件“二选一”。代码明晰易读,逻辑直白易懂。
这三种代码书写形式,功用完全一致,但观感却大相径庭。这说明,代码语句,也是需要斟酌推敲的。
Python代码
def reTuple(s):
''' 字符串还原元组 '''
lis = s.split()
result = [lis[0]]
for i in range(1, len(lis)):
#if lis[i].isdigit() and (lis[i-1].isdigit() or lis[i-1] == ')') or (lis[i] == '(' and lis[i-1].isdigit()) or (lis[i] == '(' and lis[-1] == ')'): # 饶舌复杂,差点把我自己都绕晕。
#if lis[i].isdigit() and (lis[i-1].isdigit() or lis[i-1] == ')') or lis[i] == '(' and (lis[i-1].isdigit() or lis[-1] == ')'): # 条理稍微清晰,两个嵌套if。
if lis[i].isdigit() and lis[i-1] != '(' or lis[i] == '(' and lis[i-1] != '(': # 两个并列条件的复合条件“二选一”。代码明晰易读,逻辑直白易懂。
result += [', '] + [lis[i]]
else:
result += [lis[i]]
result = ''.join(result)
return eval(result), f"{f' 字符串还原成元组 ':=^32}\n\n字符串:“{s}”\n元组:{result}\n\n{'='*40}\n"
将给定下标索引字符串,组装成下标索引tuple之元素。两个reTuple、tupleToStr功能函数都已敲定,剩下的就是按部就班地遍历输入下标索引,从元组取相应的元素输出就行了。
Python代码
def main(inStr):
lines = inStr.split('\n')
t = reTuple(lines[0])[0]
result = []
for i in lines[2:]:
#print(i) # 调试用语句。
index = ''.join([f"[{j}]" for j in i.split()[1:]])
#result += [index] # 调试用语句。
try:
result += [tupleToStr(eval(f"t{index}"))]
except:
result += ['ERROR']
input(result) # 调试用语句。
outStr = '\n'.join(map(str, result))
print(f"\n输入:\n{inStr}\n\n输出:\n{outStr}")
(源码较长,点此跳过源码)
#!/sur/bin/nve python
# coding: utf-8
def reTuple(s):
''' 字符串还原元组 '''
lis = s.split()
result = [lis[0]]
for i in range(1, len(lis)):
#if lis[i].isdigit() and (lis[i-1].isdigit() or lis[i-1] == ')') or (lis[i] == '(' and lis[i-1].isdigit()) or (lis[i] == '(' and lis[-1] == ')'): # 饶舌复杂,差点把我自己都绕晕。
#if lis[i].isdigit() and (lis[i-1].isdigit() or lis[i-1] == ')') or lis[i] == '(' and (lis[i-1].isdigit() or lis[-1] == ')'): # 条理稍微清晰,两个嵌套if。
if lis[i].isdigit() and lis[i-1] != '(' or lis[i] == '(' and lis[i-1] != '(': # 两个并列条件的复合条件“二选一”。代码明晰易读,逻辑直白易懂。
result += [', '] + [lis[i]]
else:
result += [lis[i]]
result = ''.join(result)
return eval(result), f"{f' 字符串还原成元组 ':=^32}\n\n字符串:“{s}”\n元组:{result}\n\n{'='*40}\n"
tupleToStr = lambda x: x if type(x) != tuple else f"( {' '.join(map(str, x))} )" # 如果是tuple,则搞成题目样例输入那样的“元组”。
#input(tupleToStr((5, 6, 7))) # 函数试炼语句。
def main(inStr):
lines = inStr.split('\n')
t = reTuple(lines[0])[0]
result = []
for i in lines[2:]:
#print(i) # 调试用语句。
index = ''.join([f"[{j}]" for j in i.split()[1:]])
#result += [index] # 调试用语句。
try:
result += [tupleToStr(eval(f"t{index}"))]
except:
result += ['ERROR']
input(result) # 调试用语句。
outStr = '\n'.join(map(str, result))
print(f"\n输入:\n{inStr}\n\n输出:\n{outStr}")
if __name__ == '__main__':
inStr = '''( 1 2 ( 3 4 ( 5 6 7 ) 8 ) 9 10 )
6
1 1
2 2 1
3 2 2 2
2 2 2
2 1 0
3 2 2 3'''
main(inStr) # 调用main函数完成作业。
s = '( 1 2 ( 3 4 ( 5 6 ) ) 7 ( 8 9 ) ( ) 10 )'
s2 = '( 1 2 ( 3 4 ( 5 6 7 ) 8 ) 9 10 )'
print(f"\n\n样例一:\n{reTuple(s)[1]}\n\n样例二:\n{reTuple(s2)[1]}")
我的HOT博:
本次共计收集289篇博文笔记信息,总阅读量44.72w。数据采集于2023年12月11日 23:07:13,用时5分11.8秒。阅读量不小于4.0k的有17篇。
精品文章:
来源:老齐教室
◆ Python 入门指南【Python 3.6.3】
好文力荐:
CSDN实用技巧博文: