我有不同的非常大的文件集,我想放在不同的子文件夹中。我已经为我想要使用的每个文件夹都有一个连续的ID。 我想将ID 从右侧拆分为更深层次的1000个文件夹。
示例:
id:100243
=> resul_path:'./100/243'
id:1234567890
=>结果路径:'1/234/567/890'
我找到Split string every nth character?,但所有解决方案都是从左到右,我也不想为一行代码导入另一个模块。
我当前(工作)的解决方案如下所示:
import os
base_path = '/home/made'
n=3 # take every 'n'th from the right
max_id = 12345678900
test_id = 24102442
# current algorithm
str_id = str(test_id).zfill(len(str(max_id)))
ext_path = list(reversed([str_id[max(i-n,0):i] for i in range(len(str_id),0,-n)]))
print(os.path.join(base_path, *ext_path))
输出为:/home/made/00/024/102/442
对于我想要做的简单事情,当前的算法看起来很笨拙。 我想知道是否有更好的解决方案。如果不是,它无论如何都可以帮助别人。
更新
我真的很喜欢Joe Iddons解决方案。使用.join和mod使它更快,更易读。
最后我决定我不想在前面有一个/
。要在/
为零的情况下摆脱前面的len(s)%3
,我将行更改为
'/'.join([s[max(0,i):i+3] for i in range(len(s)%3-3*(len(s)%3 != 0), len(s), 3)])
感谢您的大力帮助!
更新2:
如果您打算使用os.path.join
(就像我之前的代码一样),它更简单,因为os.path.join
负责args本身的格式:
ext_path = [s[0:len(s)%3]] + [s[i:i+3] for i in range(len(s)%3, len(s), 3)]
print(os.path.join('/home', *ext_path))
答案 0 :(得分:3)
您可以调整您关联的答案,并使用mod
的美丽来创造一个漂亮的小one-liner
:
>>> s = '1234567890'
>>> '/'.join([s[0:len(s)%3]] + [s[i:i+3] for i in range(len(s)%3, len(s), 3)])
'1/234/567/890'
如果您希望自动添加dot
,例如您的第一个示例:
s = '100243'
然后您可以按照or
的建议添加迷你三元使用@MosesKoledoye
:
>>> '/'.join(([s[0:len(s)%3] or '.']) + [s[i:i+3] for i in range(len(s)%3, len(s), 3)])
'./100/243'
此方法也比reversing
之前string
或reversing
之list
更快。
答案 1 :(得分:1)
那么如果你有一个从左到右的方向的解决方案,为什么不简单地反转输入和输出?
str = '1234567890'
str[::-1]
输出:
'0987654321'
您可以使用从左到右找到的解决方案然后再次将其反转。
答案 2 :(得分:1)
您可以使用正则表达式和模数将字符串拆分为三个一组。这个解决方案应该让你开始:
import re
s = [100243, 1234567890]
final_s = ['./'+'/'.join(re.findall('.{2}.', str(i))) if len(str(i))%3 == 0 else str(i)[:len(str(i))%3]+'/'+'/'.join(re.findall('.{2}.', str(i)[len(str(i))%3:])) for i in s]
输出:
['./100/243', '1/234/567/890']
答案 3 :(得分:1)
试试这个:
>>> line = '1234567890'
>>> n = 3
>>> rev_line = line[::-1]
>>> out = [rev_line[i:i+n][::-1] for i in range(0, len(line), n)]
>>> ['890', '567', '234', '1']
>>> "/".join(reversed(out))
>>> '1/234/567/890'