我在一个目录中有一堆文件,我想在子目录中组织。
此目录结构(哪个文件将放在哪个目录中)在文件列表中指定,如下所示:
Directory: Music\
-> 01-some_song1.mp3
-> 02-some_song2.mp3
-> 03-some_song3.mp3
Directory: Images\
-> 01-some_image1.jpg
-> 02-some_image2.jpg
......................
我正在考虑提取数据(目录名和文件名)并将其存储在如下字典中:
dictionary = {'Music': (01-some_song1.mp3, 02-some_song2.mp3,
03-some_song3.mp3),
'Images': (01-some_image1.jpg, 02-some_image2.jpg),
......................................................
}
之后我会在各自的目录中复制/移动文件。
我已经提取了目录名称并创建了空目录。
对于字典值,我尝试通过执行以下操作获取列表列表:
def get_values(file):
values = []
tmp = []
pattern = re.compile(r'^-> (.+?)$')
for line in file:
if line.strip().startswith('->'):
match = re.search(pattern, line.strip())
if match:
tmp.append(match.group(1))
elif line.strip().startswith('Directory'):
values.append(tmp)
del tmp[:]
return values
这似乎不起作用。 values
列表中的每个列表一遍又一遍地包含相同的4个文件名。
我做错了什么?
我还想知道做这件事的其他方法是什么?我确信有更好/更简单/更清洁的方式。
答案 0 :(得分:1)
我认为原因是你总是重复使用相同的列表。
del tmp[:]
清除列表,但不创建新实例。在您的情况下,您需要通过调用tmp = []
以下修复应该有效(我没有测试)
def get_values(file): values = [] tmp = [] pattern = re.compile(r'^-> (.+?)$') for line in file: if line.strip().startswith('->'): match = re.search(pattern, line.strip()) if match: tmp.append(match.group(1)) elif line.strip().startswith('Directory'): values.append(tmp) tmp = [] return values
答案 1 :(得分:1)
无需使用正则表达式
d = {}
for line in open("file"):
line=line.strip()
if line.endswith("\\"):
directory = line.split(":")[-1].strip().replace("\\","")
d.setdefault(directory,[])
if line.startswith("->"):
song=line.split(" ")[-1]
d[directory].append(song)
print d
输出
# python python.py
{'Images': ['01-some_image1.jpg', '02-some_image2.jpg'], 'Music': ['01-some_song1.mp3', '02-some_song2.mp3', '03-some_song3.mp3']}
答案 2 :(得分:0)
如果使用collections.defaultdict(list),则会得到一个列表,其中的元素是列表。如果未找到该键,则会为其添加一个空列表值,以便您可以立即开始追加该列表。这就是这条线的作用:
d[dir].append(match.group(1))
如果目录名不存在,则将其创建为密钥,并将找到的文件名附加到列表中。
顺便说一句,如果你在使用正则表达式时遇到问题,请尝试使用debug标志创建它们。我不记得符号名称,但数字是128.所以如果你这样做:file_regex = re.compile(r'^-> (.+?)$', 128)
你得到这个额外的输出:
at at_beginning
literal 45
literal 62
literal 32
subpattern 1
min_repeat 1 65535
any None
at at_end
你可以看到有一个起始线匹配' - > '(对于45 62 32)然后重复任何模式和行尾匹配。对调试非常有用。
代码:
from __future__ import with_statement
import re
import collections
def get_values(file):
d = collections.defaultdict(list)
dir = ""
dir_regex = re.compile(r'^Directory: (.+?)\\$')
file_regex = re.compile(r'\-\> (.+?)$')
with open(file) as f:
for line in f:
line = line.strip()
match = dir_regex.search(line)
if match:
dir = match.group(1)
else:
match = file_regex.search(line)
if match:
d[dir].append(match.group(1))
return d
if __name__ == '__main__':
d = get_values('test_file')
for k, v in d.items():
print k, v
结果:
Images ['01-some_image1.jpg', '02-some_image2.jpg']
Music ['01-some_song1.mp3', '02-some_song2.mp3', '03-some_song3.mp3']