我正在创建一个列出目录中现有文件的脚本,然后将它们保存到字典列表中。在目录中有两种类型的图像," foo"和" bar",在名称的末尾有一个标识符,用于知道应该查看它们的位置,例如:
foo_1.jpg
foo_2.jpg
foo_5.jpg
bar_1.jpg
bar_2.jpg
bar_3.jpg
我希望得到下一个结果:
files = [ {'position': 1, 'foo': '/img/foo_1.jpg','bar': '/img/bar_1.jpg'},
{'position': 2, 'foo': '/img/foo_2.jpg','bar': '/img/bar_2.jpg'},
{'position': 3, 'foo': '','bar': '/img/bar_3.jpg',
{'position': 5, 'foo': '/img/foo_5.jpg','bar': ''} ]
我的代码是:
def files_in_folder(folder_name):
folder_path = os.path.join(current_app.config['UPLOAD_FOLDER'], 'files', str(folder_name))
data = []
if not os.path.isdir(folder_path):
return [{}, {}, {}, {}, {}, {}, {}, {}, {}]
else:
for filename in os.listdir(folder_path):
position = int(re.search('[0-9]+', filename).group())
if "foo" in filename:
foo_register = {'position': position,
'foo': folder_path + '/' + filename,
'bar': ''}
else:
bar_register = {'position': position,
'foo': '',
'bar': folder_path + '/' + filename }
register = {**foo_register, **bar_register}
data.insert(position-1, register)
print(data)
我的结果是:
[{'foo': '', 'bar': 'uploads/campaigns/1/bar_1.png', 'position': 1},
{'foo': '', 'bar': 'uploads/campaigns/1/bar_2.png', 'position': 2},
{'foo': '', 'bar': 'uploads/campaigns/1/bar_3.png', 'position': 3},
{'foo': 'uploads/campaigns/1/foo_1.png', 'bar': '', 'position': 1,
{'foo': '', 'bar': 'uploads/campaigns/1/bar_3.png', 'position': 3}]
我的代码中缺少什么?这是最好的pythonic方式吗?
提前致谢。
答案 0 :(得分:5)
显然,我的HD上没有这些文件,所以这里有一些处理文件名列表的代码,但是为了你的目的,它应该不难调整。
此代码的核心是辅助函数CREATE TABLE `temp_table` (id int NOT NULL PRIMARY_KEY, `timestamp` int NOT NULL);
INSERT INTO `temp_table` (`id`, `timestamp`)
SELECT a.id, MAX(b.`timestamp`)
FROM `your_table` a
LEFT JOIN `your_table` b
ON b.`id` < a.`id`
WHERE a.`timestamp` = 0 AND b.`timestamp` != 0
GROUP BY a.`id`;
UPDATE `your_table` a
INNER JOIN `temp_table` b
ON b.`id` = a.`id`
SET a.`timestamp` = b.timestamp;
DROP TABLE `temp_table` ;
,它从文件名中提取位置(parse_name
)和图像类型信息(pos
)。
按照你想要的方式组织这些信息我把它写成了一个词典。然后,我们对外部字典的键进行排序,以创建所需的字典列表。我们使用数字排序,以便kind
不会在11
之前排序等等。
2
<强>输出强>
import os.path
from pprint import pprint
data = '''\
/img/foo_1.jpg
/img/foo_2.jpg
/img/foo_5.jpg
/img/bar_1.jpg
/img/bar_2.jpg
/img/bar_3.jpg
'''.splitlines()
def parse_name(s):
fname = os.path.basename(s)
fbase, _ = os.path.splitext(fname)
kind, pos = fbase.split('_')
return kind, int(pos)
files_dict = {}
for s in data:
kind, pos = parse_name(s)
d = files_dict.setdefault(pos, {'position': pos})
d[kind] = s
pprint(files_dict)
print()
files_list = [files_dict[k] for k in sorted(files_dict.keys(), key=int)]
pprint(files_list)
实际上,我们不需要那种排序键功能,因为{1: {'bar': '/img/bar_1.jpg', 'foo': '/img/foo_1.jpg', 'position': 1},
2: {'bar': '/img/bar_2.jpg', 'foo': '/img/foo_2.jpg', 'position': 2},
3: {'bar': '/img/bar_3.jpg', 'position': 3},
5: {'foo': '/img/foo_5.jpg', 'position': 5}}
[{'bar': '/img/bar_1.jpg', 'foo': '/img/foo_1.jpg', 'position': 1},
{'bar': '/img/bar_2.jpg', 'foo': '/img/foo_2.jpg', 'position': 2},
{'bar': '/img/bar_3.jpg', 'position': 3},
{'foo': '/img/foo_5.jpg', 'position': 5}]
已经转换为pos
中的int
。哎呀! :)所以我们可以这样做:
parse_name
files_list = [files_dict[k] for k in sorted(files_dict.keys())]
循环可以压缩到:
for
虽然这比之前的版本更加神秘。 ;)
for s in data:
kind, pos = parse_name(s)
files_dict.setdefault(pos, {'position': pos})[kind] = s
使用密钥files_dict.setdefault(pos, {'position': pos})
在files_dict
中获取子字典。如果它不存在,则使用初始键值对pos
创建。
然后我们使用('position', pos)
更新该子字典,其中(kind, s)
是当前文件的完整文件名。
答案 1 :(得分:1)
尝试使用filename.startswith('bar')
或filename.startswith('foo')
区分foo_1.jpg
和bar_1.jpg
尝试使用position=int(os.path.splitext(filename)[0].split('_')[-1])
代替re
。
register = {**foo_register, **bar_register}
:e.g。
a={'foo': '', 'bar': 'uploads/campaigns/1/bar_1.png', 'position': 1}
b={'foo': 'uploads/campaigns/1/foo_.png', 'bar': '', 'position': 1}
print({**a,**b})
输出:
{'foo': 'uploads/campaigns/1/foo_.png', 'bar': '', 'position': 1}
我认为这就是你得到意想不到的结果的原因。
你可以试试这个:
a.update({k:v for k,v in b.items() if v})
print(a)
输出:
{'foo': 'uploads/campaigns/1/foo_.png', 'bar': 'uploads/campaigns/1/bar_1.png', 'position': 1}
答案 2 :(得分:0)
import os, re
cwd = os.getcwd()
print cwd
def update(li, pos, path, key):
added = False
if len(li) == 0:
di=dict()
di["position"] = int(pos)
di[key] = path
li.append(di)
added = True
else:
for di in li:
if di["position"]==pos:
di[key] = path
added = True
if not added:
di=dict()
di["position"] = int(pos)
di[key] = path
li.append(di)
li = []
for filename in os.listdir(cwd+r'/try'): # folder name where my files are.
position = int(re.search('[0-9]+', filename).group())
print filename, position
path = cwd + '/' + filename
if "foo" in filename:
update(li, position, path, "foo")
elif "bar" in filename:
update(li, position, path, "bar")
print li