我想知道是否可以在python3中强制os.walk按字母顺序访问目录。例如,这是一个目录和一些将遍历此目录的代码:
ryan:~/bktest$ ls -1 sample
CD01
CD02
CD03
CD04
CD05
--------
def main_work_subdirs(gl):
for root, dirs, files in os.walk(gl['pwd']):
if root == gl['pwd']:
for d2i in dirs:
print(d2i)
当python代码点击上面的目录时,这里是输出:
ryan:~/bktest$ ~/test.py sample
CD03
CD01
CD05
CD02
CD04
我想强制步行按字母顺序访问这些目录,01, 02 ... 05
。在python3 doc for os.walk
中,它说:
当topdown为True时,调用者可以就地修改dirnames列表 (可能使用del或slice赋值),而walk()只会递归 进入名称保留在dirnames中的子目录;这可以 用于修剪搜索,强制执行特定的访问顺序
这是否意味着我可以在os.walk
上强加按字母顺序排列的访问顺序?如果是这样,怎么样?
答案 0 :(得分:31)
是。你在循环中对dirs进行排序。
def main_work_subdirs(gl):
for root, dirs, files in os.walk(gl['pwd']):
dirs.sort()
if root == gl['pwd']:
for d2i in dirs:
print(d2i)
答案 1 :(得分:2)
我知道这已经得到了解答,但我想补充一点细节,在评论中添加多行代码是不可能的。
除了想要排序的目录之外,我还希望对文件进行排序,以便我通过“gl”的迭代是一致且可预测的。要做到这一点,还需要更多种类:
for root, dirs, files in os.walk(gl):
dirs.sort()
for filename in sorted(files):
print(os.path.join(root, filename))
答案 2 :(得分:1)
此答案并非特定于此问题,并且问题有所不同,但是无论哪种情况都可以使用该解决方案。
考虑拥有这些文件("one1.txt"
,"one2.txt"
,"one10.txt"
),所有文件的内容都是字符串"default"
:
我想遍历包含这些文件的目录,并在每个文件中找到一个特定的String并将其替换为文件名。
如果您使用此处已经提及的其他方法以及其他问题(例如dirs.sort()
和sorted(files)
和sorted(dirs)
,则结果将是这样的:
"one1.txt"--> "one10"
"one2.txt"--> "one1"
"one10.txt" --> "one2"
但是我们希望它是:
"one1.txt"--> "one1"
"one2.txt"--> "one2"
"one10.txt" --> "one10"
我发现这种方法可以按字母顺序更改文件内容:
import re, os, fnmatch
def atoi(text):
return int(text) if text.isdigit() else text
def natural_keys(text):
'''
alist.sort(key=natural_keys) sorts in human order
http://nedbatchelder.com/blog/200712/human_sorting.html
(See Toothy's implementation in the comments)
'''
return [ atoi(c) for c in re.split('(\d+)', text) ]
def findReplace(directory, find, replace, filePattern):
count = 0
for path, dirs, files in sorted(os.walk(os.path.abspath(directory))):
dirs.sort()
for filename in sorted(fnmatch.filter(files, filePattern), key=natural_keys):
count = count +1
filepath = os.path.join(path, filename)
with open(filepath) as f:
s = f.read()
s = s.replace(find, replace+str(count)+".png")
with open(filepath, "w") as f:
f.write(s)
然后运行此行:
findReplace(os.getcwd(), "default", "one", "*.xml")