Python 从右边每隔N个字符拆分一个字符串?

Python 从右边每隔N个字符拆分一个字符串?,python,string,list-comprehension,Python,String,List Comprehension,我有不同的非常大的文件集,我想把它们放在不同的子文件夹中。我想使用的每个文件夹都有一个连续的ID。 我想从右侧拆分ID,以便在更深层次中始终有1000个文件夹 示例: id:100243=>结果路径:'./100/243' id:1234567890=>结果路径:'1/234/567/890' 我找到了,但所有的解决方案都是从左到右的,我也不想为一行代码导入另一个模块 我当前的(工作)解决方案如下所示: import os base_path = '/home/made' n=3 # t

我有不同的非常大的文件集,我想把它们放在不同的子文件夹中。我想使用的每个文件夹都有一个连续的ID。 我想从右侧拆分ID,以便在更深层次中始终有1000个文件夹

示例

id:
100243
=>结果路径:
'./100/243'

id:
1234567890
=>结果路径:
'1/234/567/890'

我找到了,但所有的解决方案都是从左到右的,我也不想为一行代码导入另一个模块

我当前的(工作)解决方案如下所示:

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

对于我想做的简单事情来说,当前的算法看起来既笨拙又复杂。 我想知道是否有更好的解决办法。如果不是,它可能会帮助其他人,无论如何

更新:

我真的很喜欢乔·艾登的解决方案。使用.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
会处理参数本身的格式:

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))

那么,如果你得到了从左到右方向的解决方案,为什么不简单地反转输入和输出呢

str = '1234567890'
str[::-1]
输出:

'0987654321'
['./100/243', '1/234/567/890']

您可以使用从左到右找到的解决方案,然后只需再次反转即可。

您可以使用regex和modulo将字符串分成三组。此解决方案应该让您开始:

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]
输出:

'0987654321'
['./100/243', '1/234/567/890']
试试这个:

>>> 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'

您可以调整链接的答案,并利用
mod
的美丽创建一个漂亮的
一行代码

>>> 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'
如果您想在第一个示例中自动添加

s = '100243'
然后,您只需添加一个小型三元用法
,如
@MosesKoledoye
所示:

>>> '/'.join(([s[0:len(s)%3] or '.']) + [s[i:i+3] for i in range(len(s)%3, len(s), 3)])
'./100/243'

此方法也将比手前的
字符串
字符串
反转
a
列表

将“最大ID长度”四舍五入到n的最接近倍数是否可以接受?也就是说,如果第一个路径段的长度始终为n个字符,可以吗?这里是一个起点。。。从您提供的链接中修改答案到这个
[line[i-n:i]for i in range(len(line),0,-n)]
会让您
['890','567','234','']
@DanielPryden:这不会是一个问题。这个解决方案应该会让您开始。我对此表示怀疑。很难辨认,谢谢!我想这正是塞格·阿努克(Serg Anuke)在上面的回答中所做的。你可以做的不是三元:
[s[0:len(s)%3]或“.”
@MosesKoledoye这确实很好!