2017-06-20 60 views
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 

所以可以這樣在更Python一個襯墊的方法呢?如果不是,其他更自動的方法是什麼呢?

回答

1
>>> 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 
+1

感謝您的回答。輸出是 - '--- 19f75e3f' – ShellRox

+0

現在輸出結果是 - '--19f7-5e3' – ShellRox

+0

@ShellRox有點晚了,但是這裏是一個沒有itertools的1班輪。請注意,它是低效的,因爲它不斷調用總和。但它的工作。 –

4

遞增地使用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)的總大小不等於的長度串;迭代器不完全耗盡。

您可以追加尾隨部分(如果需要)在最終的預處理階段:

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 
+0

感謝您的回答,如果沒有itertools的幫助,它是正確的嗎? – ShellRox

+0

@ShellRox任何不想使用itertools的原因? –

+0

Kolodoye我只是想避免額外使用模塊,但如果沒有其他簡單的方法,那麼這不是一個問題。 – ShellRox

0

不是一個線性恐怕,但是從我的頭的頂部:

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

如果我們從列出的數據開始:

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

我們可以用掃描發現ŧ他作beginnings或各部分的兩端:

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

看來accumulate是具體到Python 3,所以我們可能需要一種解決方法做掃描在Python 2(這一個在澳慢(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

感謝您的答案,絕對有用,但我試圖找到解決方案,它只使用普通的python。 – ShellRox

+1

這是不是普通的Python?這都是標準庫。 –

+0

對不起,誤解,我的意思是我試圖避免在這種情況下使用模塊,因爲它是可能的。 – ShellRox

1
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)) 
相關問題