在bash中,python可以这样做吗?
python可以通过这样的简短语法生成具有多个子路径的路径吗在bash中,python可以这样做吗?,python,shell,path,glob,expansion,Python,Shell,Path,Glob,Expansion,python可以通过这样的简短语法生成具有多个子路径的路径吗 vars=project/{DEBIAN,usr/{bin,usr/{applications,icons,share}},computer} 不,没有这样的内置速记。一个合理的python方法是: vars = ["project" + path for path in ( ["/DEBIAN"] + ["/usr" + path for path in
vars=project/{DEBIAN,usr/{bin,usr/{applications,icons,share}},computer}
不,没有这样的内置速记。一个合理的python方法是:
vars = ["project" + path for path in (
["/DEBIAN"] +
["/usr" + path for path in (
['/bin'] +
['/usr' + path for path in [
"/applications",
"/icons",
"/share"]
]
)] +
['/computer']
)]
编辑: 您可以定义一个函数来简化此操作。这是一个惰性生成器版本:
def展开(基本路径):
对于路径中的路径:
如果类型(路径)==str:
产量基数+路径
其他:
对于路径中的p:
产量基数+p
vars=expand(“项目”[
“/debian”,
展开(“/usr”[
“/bin”,
展开(“/usr”[
“/应用程序”,
“/图标”,
“/份”
]),
“/计算机”
])
])
谢谢
我试着写我的代码
我总是用[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']
通常我会建议使用类似
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.
如果需要,可以使用字符串解析方法。我认为这是在单个语句中执行此操作的最佳方法。您的代码很臭,因为它无缘无故地使用
eval()
。我试图改进它…^。^对不起。我懒得定义循环和函数,我的编程知识和我的英语技能一样糟糕。我只是用这段代码来构建我的debian包项目。然而,我希望有人能给我们更多更高的代码。非常感谢。D> >>打印列表(commasplit(cs))35;->似乎有效['a','b','c','D,e,f}','g']@UhBaUnTaUh没错。它有意只在第一级工作split()
递归调用自身,因此最终一切都应该是正确的。您让我更多地了解了yield和enumerate,我变得熟悉了normal return,这让我养成了一些糟糕的编程习惯。另外,您的代码让我想起了关于解释器/编译器编程的内容。谢谢。对不起,我是这种编码风格的新手。我试着阅读你们的代码,以我想要的方式修改它,但我不了解iter的概念,所以我不知道如何修改它。你能帮我把你的代码修改成这种风格吗?pythonGenPath(“project,[DEBIAN,usr,[bin,usr,[applications,icons,share/winpath]],computer]”我认为这将是一种创建列表的有用方法,而不需要双引号。我想修改它以生成多维无双引号字符串列表。