首页 文章

将字符串拆分为不同长度的块

提问于
浏览
0

为了正确格式化字符串,我需要将其拆分为不同长度的块 .

举个例子,这是一个字符串 - 25c319f75e3fbed5a9f0497750ea12992b30d565 ,为了将它拆分成固定长度的块,我只需要使用步骤和切片:

s = '25c319f75e3fbed5a9f0497750ea12992b30d565'
n = 2
print("-".join([s[i:i+n] for i in range(0, len(s), n)]))

但是,如果 n 是要拆分的数字列表,我该怎么办?例如:

s = '25c319f75e3fbed5a9f0497750ea12992b30d565'
n = [8, 4, 4, 4, 4, 12] # edited for consistency - Coldspeed

我做的唯一解决方案就是:

print("-".join([s[0:8], s[8:12], s[12:16], s[16:20], s[20:24], s[24:32]]))

哪个不是pythonic,更不一定不可靠的字符串长度很大 .

最后一个代码示例的输出:

25c319f7-5e3f-bed5-a9f0-4977-50ea1299

那么这可以用更多的pythonic单线方式来完成吗?如果没有,还有什么其他更自动的方法呢?

5 回答

  • 1

    我担心的不是单线性的,而是从我的头脑中:

    s = '25c319f75e3fbed5a9f0497750ea12992b30d565'
    n = [8, 4, 4, 4, 4, 12]
    res=[]
    for split in n:
        temp=s[:split]
        s=s[split:]
        res.append(temp) 
    print(res)
    

    输出是一个数组,其中包含可以相应操作的相应字符串:

    ['25c319f7', '5e3f', 'bed5', 'a9f0', '4977', '50ea12992b30']
    
  • 5
    >>> s = '25c319f75e3fbed5a9f0497750ea12992b30d565'
    >>> n = [8, 4, 4, 4, 4, 12]
    >>> print '-'.join([s[sum(n[:i]) : sum(n[:i+1])] for i in range(len(n))  ])
    

    产量

    25c319f7-5e3f-bed5-a9f0-4977-50ea12992b30
    
  • 0

    使用itertools.islice以增量方式从字符串和切片创建迭代器:

    from itertools import islice
    
    s = '25c319f75e3fbed5a9f0497750ea12992b30d565'
    it = iter(s)
    n = [8, 4, 4, 12]
    
    s = '-'.join(''.join(islice(it, None, x)) for x in n)
    print(s)
    # 25c319f7-5e3f-bed5-a9f0497750ea
    

    请注意,如果切片的总大小不等于字符串的长度,则字符串的尾部会丢失;迭代器并没有完全耗尽 .

    您可以在最终预处理阶段追加尾部(如果需要):

    s += '-' + ''.join(it)
    print(s)
    # 25c319f7-5e3f-bed5-a9f0497750ea-12992b30d565
    

    这是另一种使用for循环的方法,通过增加起始索引逐步切割字符串:

    start = 0
    d = []
    for i in n:
       d.append(s[start:start+i])
       start += i
    d.append(s[start:])
    print('-'.join(d))
    # 25c319f7-5e3f-bed5-a9f0497750ea-12992b30d565
    
  • 1

    如果我们从列出的数据开始:

    string = '25c319f75e3fbed5a9f0497750ea12992b30d565'
    lengths = [8, 4, 4, 12]
    

    我们可以使用扫描来查找每个部分的开头或结尾:

    import itertools
    ends = list(itertools.accumulate(lengths))
    

    看起来 accumulate 特定于Python 3,因此我们可能需要一种解决方法来在Python 2中进行扫描(这个在O(n²)处慢):

    starts = [sum(lengths[:i]) for i in range(len(lengths))]
    

    然后我们可以使用组合来提取部件:

    dashed = '-'.join(string[end-length : end]
                      for end,length in zip(ends,lengths))
    

    所有这些长度/索引操作的优点是它不会创建字符串的副本,只创建其各个部分 . 否则肖恩的解决方案非常整洁 .

  • 0
    s = '25c319f75e3fbed5a9f0497750ea12992b30d565'
    n = [8, 4, 4, 12]
    
    def make_chunks(s,n):
        result = []
        for length in n:
            result.append(s[:length])
            s = s[length:]
        if s:
            result.append(s)
        return '-'.join(result)
    
    print(make_chunks(s,n))
    

相关问题