python可以通过这样的短格式语法生成具有多子路径的路径吗?
vars=project/{DEBIAN,usr/{bin,usr/{applications,icons,share}},computer}
通常我会建议使用类似的东西
def extend(base, *others):
[base + o for o in others] if others else [base]
然后做
extend("project", "/debian", *extend("/usr", *(extend("/bin") + extend("/usr", "/applications", "/icons", "/share"))))
. 但是由于您更喜欢解析字符串,我尝试提供一种替代方法:
def commasplit(s):
start = 0
level = 0
for i, c in enumerate(s):
if c == '{':
level += 1
elif c == '}':
level -= 1
elif c == ',' and level == 0:
yield s[start:i]
start = i+1
yield s[start:]
def split(s):
import re
found = False
for m in re.finditer("(\{.*\})",s):
found = True
for p in commasplit(s[m.start() + 1:m.end() - 1]):
for i in split(p):
yield s[:m.start()] + i + s[m.end():]
if not found:
yield s
cs = "a,b,c,{d,e,f},g"
print list(commasplit(cs)) # -> seems to work
s = "project/{DEBIAN,usr/{bin,usr/{applications,icons,share}},computer}"
print s
for n, i in enumerate(split(s)): print n, i # -> as well.
不,没有这样的内置速记。一个合理的pythonic方式是:
vars = ["project" + path for path in (
["/DEBIAN"] +
["/usr" + path for path in (
['/bin'] +
['/usr' + path for path in [
"/applications",
"/icons",
"/share"]
]
)] +
['/computer']
)]
您可以定义一个函数来简化此操作。这是一个惰性生成器版本:
def expand(base, paths):
for path in paths:
if type(path) == str:
yield base + path
else:
for p in path:
yield base + p
vars = expand("project", [
"/debian",
expand("/usr", [
"/bin",
expand("/usr", [
"/applications",
"/icons",
"/share"
]),
"/computer"
])
])
谢谢你。
我尝试编写我的代码。
我总是使用 ["0,1,2,3,4,5,6,7,8,9".split(","),["a,b,c,d,e".split(", ")]] 而不是普通的列表。
因为它比 ["x","y","z"] 更快——不用换档,很明显,而且更有意义。
所以,我希望很快会有一些字符串方法可以像bash一样,下面的代码,在python中......
Python 语法:project,[DEBIAN,usr,[bin,usr,[applications,icons,share/winpath]],computer]
Bash 语法:project/{DEBIAN,usr/{bin,usr/{applications,icons,share}},computer}
import re
def genpaths (multils, root=""):
suc=[]
for l in multils:
if type(l) == type([]):
suc.extend(genpaths (l, root+multils[multils.index(l)-1]+"/"))
else:
suc.append( root+l)
return filter(None, suc)
def easylist (s):
s=eval("['''"+re.sub("(\]+)(''',''')?", "'''\\1,'''",re.sub("(''',''')?(\[+)","''',\\2'''",re.sub(",","''','''",s)))+"''']")
return s
def bashlist (s):
s=eval("['''"+re.sub("(\}+)(''',''')?", "'''\\1,'''",re.sub("(/)?(\{+)","''',\\2'''",re.sub(",","''','''",s))).replace("{","[").replace("}","]")+"''']")
return s
def pythonGenPath (s):
return genpaths(bashlist (s))
def bashGenPath (s):
return genpaths(bashlist (s))
#testing
print pythonGenPath ("project,[DEBIAN,usr,[bin,usr,[applications,icons,share/winpath]],computer]")
print bashGenPath ("project/{DEBIAN,usr/{bin,usr/{applications,icons,share}},computer}")
结果是:
['project', 'project/DEBIAN', 'project/usr', 'project/usr/bin', 'project/usr/usr', 'project/usr/usr/applications', 'project/usr/usr/icons', 'project/usr/usr/share', 'project/computer']