问题:每n个字符分割一个字符串?
是否可以每n个字符分割一个字符串?
例如,假设我有一个包含以下内容的字符串:
'1234567890'
我怎样才能使它看起来像这样:
['12','34','56','78','90']
Is it possible to split a string every nth character?
For example, suppose I have a string containing the following:
'1234567890'
How can I get it to look like this:
['12','34','56','78','90']
回答 0
>>> line = '1234567890'
>>> n = 2
>>> [line[i:i+n] for i in range(0, len(line), n)]
['12', '34', '56', '78', '90']
>>> line = '1234567890'
>>> n = 2
>>> [line[i:i+n] for i in range(0, len(line), n)]
['12', '34', '56', '78', '90']
回答 1
为了完整起见,您可以使用正则表达式执行此操作:
>>> import re
>>> re.findall('..','1234567890')
['12', '34', '56', '78', '90']
对于字符的奇数,您可以执行以下操作:
>>> import re
>>> re.findall('..?', '123456789')
['12', '34', '56', '78', '9']
您还可以执行以下操作,以简化较长块的正则表达式:
>>> import re
>>> re.findall('.{1,2}', '123456789')
['12', '34', '56', '78', '9']
re.finditer
如果字符串很长,则可以使用它逐块生成。
Just to be complete, you can do this with a regex:
>>> import re
>>> re.findall('..','1234567890')
['12', '34', '56', '78', '90']
For odd number of chars you can do this:
>>> import re
>>> re.findall('..?', '123456789')
['12', '34', '56', '78', '9']
You can also do the following, to simplify the regex for longer chunks:
>>> import re
>>> re.findall('.{1,2}', '123456789')
['12', '34', '56', '78', '9']
And you can use re.finditer
if the string is long to generate chunk by chunk.
回答 2
在python中已经有一个内置函数。
>>> from textwrap import wrap
>>> s = '1234567890'
>>> wrap(s, 2)
['12', '34', '56', '78', '90']
这是wrap的文档字符串所说的:
>>> help(wrap)
'''
Help on function wrap in module textwrap:
wrap(text, width=70, **kwargs)
Wrap a single paragraph of text, returning a list of wrapped lines.
Reformat the single paragraph in 'text' so it fits in lines of no
more than 'width' columns, and return a list of wrapped lines. By
default, tabs in 'text' are expanded with string.expandtabs(), and
all other whitespace characters (including newline) are converted to
space. See TextWrapper class for available keyword args to customize
wrapping behaviour.
'''
There is already an inbuilt function in python for this.
>>> from textwrap import wrap
>>> s = '1234567890'
>>> wrap(s, 2)
['12', '34', '56', '78', '90']
This is what the docstring for wrap says:
>>> help(wrap)
'''
Help on function wrap in module textwrap:
wrap(text, width=70, **kwargs)
Wrap a single paragraph of text, returning a list of wrapped lines.
Reformat the single paragraph in 'text' so it fits in lines of no
more than 'width' columns, and return a list of wrapped lines. By
default, tabs in 'text' are expanded with string.expandtabs(), and
all other whitespace characters (including newline) are converted to
space. See TextWrapper class for available keyword args to customize
wrapping behaviour.
'''
回答 3
将元素分组为n个长度的组的另一种常见方式:
>>> s = '1234567890'
>>> map(''.join, zip(*[iter(s)]*2))
['12', '34', '56', '78', '90']
此方法直接来自的文档zip()
。
Another common way of grouping elements into n-length groups:
>>> s = '1234567890'
>>> map(''.join, zip(*[iter(s)]*2))
['12', '34', '56', '78', '90']
This method comes straight from the docs for zip()
.
回答 4
我认为这比itertools版本更短,更易读:
def split_by_n(seq, n):
'''A generator to divide a sequence into chunks of n units.'''
while seq:
yield seq[:n]
seq = seq[n:]
print(list(split_by_n('1234567890', 2)))
I think this is shorter and more readable than the itertools version:
def split_by_n(seq, n):
'''A generator to divide a sequence into chunks of n units.'''
while seq:
yield seq[:n]
seq = seq[n:]
print(list(split_by_n('1234567890', 2)))
回答 5
我喜欢这个解决方案:
s = '1234567890'
o = []
while s:
o.append(s[:2])
s = s[2:]
I like this solution:
s = '1234567890'
o = []
while s:
o.append(s[:2])
s = s[2:]
回答 6
使用PyPI的more-itertools:
>>> from more_itertools import sliced
>>> list(sliced('1234567890', 2))
['12', '34', '56', '78', '90']
Using more-itertools from PyPI:
>>> from more_itertools import sliced
>>> list(sliced('1234567890', 2))
['12', '34', '56', '78', '90']
回答 7
您可以使用以下grouper()
配方itertools
:
Python 2.x:
from itertools import izip_longest
def grouper(iterable, n, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)
Python 3.x:
from itertools import zip_longest
def grouper(iterable, n, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
return zip_longest(*args, fillvalue=fillvalue)
这些函数可节省内存,并且可与任何可迭代对象一起使用。
You could use the grouper()
recipe from itertools
:
Python 2.x:
from itertools import izip_longest
def grouper(iterable, n, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)
Python 3.x:
from itertools import zip_longest
def grouper(iterable, n, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
return zip_longest(*args, fillvalue=fillvalue)
These functions are memory-efficient and work with any iterables.
回答 8
尝试以下代码:
from itertools import islice
def split_every(n, iterable):
i = iter(iterable)
piece = list(islice(i, n))
while piece:
yield piece
piece = list(islice(i, n))
s = '1234567890'
print list(split_every(2, list(s)))
Try the following code:
from itertools import islice
def split_every(n, iterable):
i = iter(iterable)
piece = list(islice(i, n))
while piece:
yield piece
piece = list(islice(i, n))
s = '1234567890'
print list(split_every(2, list(s)))
回答 9
>>> from functools import reduce
>>> from operator import add
>>> from itertools import izip
>>> x = iter('1234567890')
>>> [reduce(add, tup) for tup in izip(x, x)]
['12', '34', '56', '78', '90']
>>> x = iter('1234567890')
>>> [reduce(add, tup) for tup in izip(x, x, x)]
['123', '456', '789']
>>> from functools import reduce
>>> from operator import add
>>> from itertools import izip
>>> x = iter('1234567890')
>>> [reduce(add, tup) for tup in izip(x, x)]
['12', '34', '56', '78', '90']
>>> x = iter('1234567890')
>>> [reduce(add, tup) for tup in izip(x, x, x)]
['123', '456', '789']
回答 10
尝试这个:
s='1234567890'
print([s[idx:idx+2] for idx,val in enumerate(s) if idx%2 == 0])
输出:
['12', '34', '56', '78', '90']
Try this:
s='1234567890'
print([s[idx:idx+2] for idx,val in enumerate(s) if idx%2 == 0])
Output:
['12', '34', '56', '78', '90']
回答 11
一如既往,对于那些喜欢一只班轮的人
n = 2
line = "this is a line split into n characters"
line = [line[i * n:i * n+n] for i,blah in enumerate(line[::n])]
As always, for those who love one liners
n = 2
line = "this is a line split into n characters"
line = [line[i * n:i * n+n] for i,blah in enumerate(line[::n])]
回答 12
一个短字符串的简单递归解决方案:
def split(s, n):
if len(s) < n:
return []
else:
return [s[:n]] + split(s[n:], n)
print(split('1234567890', 2))
或以这种形式:
def split(s, n):
if len(s) < n:
return []
elif len(s) == n:
return [s]
else:
return split(s[:n], n) + split(s[n:], n)
,它更明确地说明了递归方法中的典型分而治之模式(尽管实际上没有必要这样做)
A simple recursive solution for short string:
def split(s, n):
if len(s) < n:
return []
else:
return [s[:n]] + split(s[n:], n)
print(split('1234567890', 2))
Or in such a form:
def split(s, n):
if len(s) < n:
return []
elif len(s) == n:
return [s]
else:
return split(s[:n], n) + split(s[n:], n)
, which illustrates the typical divide and conquer pattern in recursive approach more explicitly (though practically it is not necessary to do it this way)
回答 13
我陷入了同一个场景。
这对我有用
x="1234567890"
n=2
list=[]
for i in range(0,len(x),n):
list.append(x[i:i+n])
print(list)
输出量
['12', '34', '56', '78', '90']
I was stucked in the same scenrio.
This worked for me
x="1234567890"
n=2
list=[]
for i in range(0,len(x),n):
list.append(x[i:i+n])
print(list)
Output
['12', '34', '56', '78', '90']
回答 14
more_itertools.sliced
之前已经提到过。这是more_itertools
库中的另外四个选项:
s = "1234567890"
["".join(c) for c in mit.grouper(2, s)]
["".join(c) for c in mit.chunked(s, 2)]
["".join(c) for c in mit.windowed(s, 2, step=2)]
["".join(c) for c in mit.split_after(s, lambda x: int(x) % 2 == 0)]
后面的每个选项均产生以下输出:
['12', '34', '56', '78', '90']
所讨论的选项的说明文档:grouper
,chunked
,windowed
,split_after
more_itertools.sliced
has been mentioned before. Here are four more options from the more_itertools
library:
s = "1234567890"
["".join(c) for c in mit.grouper(2, s)]
["".join(c) for c in mit.chunked(s, 2)]
["".join(c) for c in mit.windowed(s, 2, step=2)]
["".join(c) for c in mit.split_after(s, lambda x: int(x) % 2 == 0)]
Each of the latter options produce the following output:
['12', '34', '56', '78', '90']
Documentation for discussed options: grouper
, chunked
, windowed
, split_after
回答 15
这可以通过简单的for循环来实现。
a = '1234567890a'
result = []
for i in range(0, len(a), 2):
result.append(a[i : i + 2])
print(result)
输出看起来像[’12’,’34’,’56’,’78’,’90’,’a’]
This can be achieved by a simple for loop.
a = '1234567890a'
result = []
for i in range(0, len(a), 2):
result.append(a[i : i + 2])
print(result)
The output looks like
[’12’, ’34’, ’56’, ’78’, ’90’, ‘a’]