将 Python 中的字符串拆分为长度恒定但右对齐的块
Split string in Python into chunks with constant length, but right-aligned
基本上,我有一个像“12345678”这样的字符串,需要一个包含此信息的列表,但要分成长度为 3 的子字符串。问题是,我需要它右对齐,所以输出必须是['12', '345', '678']
而不是 ['123', '456', '78']
.
我如何用很少的代码行最好地实现并且最好没有额外的导入?
改编来自 How do you split a list into evenly sized chunks? 的最佳答案很容易:
def chunks_rightaligned(l, n):
orphan = len(l) % n
if orphan:
yield l[:orphan]
for i in xrange(orphan, len(l), n):
yield l[i:i+n]
这首先产生剩余长度的块,然后从孤立大小而不是 0 开始以块大小的步长迭代索引。
演示:
>>> def chunks_rightaligned(l, n):
... orphan = len(l) % n
... if orphan:
... yield l[:orphan]
... for i in xrange(orphan, len(l), n):
... yield l[i:i+n]
...
>>> list(chunks_rightaligned("12345678", 3))
['12', '345', '678']
>>> list(chunks_rightaligned("1234567", 3))
['1', '234', '567']
>>> list(chunks_rightaligned("123456", 3))
['123', '456']
如果你想尝试正则表达式,可以使用re.split()
函数
>>> re.split(r"(...)(?=(?:\d\d\d)+$)","12345678")
['12', '345', '678']
>>> re.split(r"(...)(?=(?:\d\d\d)+$)","123")
['123']
编辑
更好的解决方案是使用 re.findall()
>>> re.findall(r"\d{1,3}(?=(?:\d{3})*$)", "12345")
['12', '345']
>>> re.findall(r"\d{1,3}(?=(?:\d{3})*$)", "123456")
['123', '456']
>>> re.findall(r"\d{1,3}(?=(?:\d{3})*$)", "1234567")
['1', '234', '567']
它有什么作用?
\d{1,3}
最多匹配 3 个字符,最少匹配 1 个字符。
(?=(?:\d{3})*$)
积极展望。确保匹配的字符后跟 3 位数的倍数。
(?:\d{3})
匹配 3 个数字。
您可以在正则表达式字符串中使用变量来生成可变数据块。
例子
>>> $limit=4
>>> regex = r"\d{1,%d}(?=(?:\d{%d})*$)" %(limit,limit)
>>> re.findall(regex, "1234567")
['123', '4567']
>>> limit=3
>>> regex = r"\d{1,%d}(?=(?:\d{%d})*$)" %(limit,limit)
>>> re.findall(regex, "1234567")
['1', '234', '567']
基本上,我有一个像“12345678”这样的字符串,需要一个包含此信息的列表,但要分成长度为 3 的子字符串。问题是,我需要它右对齐,所以输出必须是['12', '345', '678']
而不是 ['123', '456', '78']
.
我如何用很少的代码行最好地实现并且最好没有额外的导入?
改编来自 How do you split a list into evenly sized chunks? 的最佳答案很容易:
def chunks_rightaligned(l, n):
orphan = len(l) % n
if orphan:
yield l[:orphan]
for i in xrange(orphan, len(l), n):
yield l[i:i+n]
这首先产生剩余长度的块,然后从孤立大小而不是 0 开始以块大小的步长迭代索引。
演示:
>>> def chunks_rightaligned(l, n):
... orphan = len(l) % n
... if orphan:
... yield l[:orphan]
... for i in xrange(orphan, len(l), n):
... yield l[i:i+n]
...
>>> list(chunks_rightaligned("12345678", 3))
['12', '345', '678']
>>> list(chunks_rightaligned("1234567", 3))
['1', '234', '567']
>>> list(chunks_rightaligned("123456", 3))
['123', '456']
如果你想尝试正则表达式,可以使用re.split()
函数
>>> re.split(r"(...)(?=(?:\d\d\d)+$)","12345678")
['12', '345', '678']
>>> re.split(r"(...)(?=(?:\d\d\d)+$)","123")
['123']
编辑
更好的解决方案是使用 re.findall()
>>> re.findall(r"\d{1,3}(?=(?:\d{3})*$)", "12345")
['12', '345']
>>> re.findall(r"\d{1,3}(?=(?:\d{3})*$)", "123456")
['123', '456']
>>> re.findall(r"\d{1,3}(?=(?:\d{3})*$)", "1234567")
['1', '234', '567']
它有什么作用?
\d{1,3}
最多匹配 3 个字符,最少匹配 1 个字符。(?=(?:\d{3})*$)
积极展望。确保匹配的字符后跟 3 位数的倍数。(?:\d{3})
匹配 3 个数字。
您可以在正则表达式字符串中使用变量来生成可变数据块。
例子
>>> $limit=4
>>> regex = r"\d{1,%d}(?=(?:\d{%d})*$)" %(limit,limit)
>>> re.findall(regex, "1234567")
['123', '4567']
>>> limit=3
>>> regex = r"\d{1,%d}(?=(?:\d{%d})*$)" %(limit,limit)
>>> re.findall(regex, "1234567")
['1', '234', '567']