Answers:
>>> line = '1234567890'
>>> n = 2
>>> [line[i:i+n] for i in range(0, len(line), n)]
['12', '34', '56', '78', '90']
为了完整起见,您可以使用正则表达式执行此操作:
>>> 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
如果字符串很长,则可以使用它逐块生成。
'.'*n
更清楚。没有加入,没有压缩,没有循环,没有列表理解;只需找到彼此相邻的下两个字符,这正是人脑对此的思考。如果Monty Python还活着,他一定会喜欢这种方法!
flags=re.S
。
在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.
'''
wrap
可能不会返回字符串是否包含空格的要求。例如wrap('0 1 2 3 4 5', 2)
回报['0', '1', '2', '3', '4', '5']
(元素被剥离)
将元素分组为n个长度的组的另一种常见方式:
>>> s = '1234567890'
>>> map(''.join, zip(*[iter(s)]*2))
['12', '34', '56', '78', '90']
此方法直接来自的文档zip()
。
zip(*[iter(s)]*2)
难以理解,请阅读如何zip(*[iter(s)]*n)
在Python 中工作?。
>>> map(''.join, zip(*[iter('01234567')]*5))
->['01234']
zip()
为itertools.zip_longest()
:map(''.join, zip_longest(*[iter(s)]*2, fillvalue=''))
maps()
我认为这比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)))
使用PyPI的more-itertools:
>>> from more_itertools import sliced
>>> list(sliced('1234567890', 2))
['12', '34', '56', '78', '90']
您可以使用以下grouper()
配方itertools
:
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)
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)
这些函数可节省内存,并且可与任何可迭代对象一起使用。
尝试以下代码:
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)))
yield ''.join(piece)
它来使其按预期的方式运行:eval.in/813878
>>> 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']
一如既往,对于那些喜欢一只班轮的人
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])]
print(line)
得到this is a line split into n characters
输出。你可能会更好地投入:line = [line[i * n:i * n+n] for i,blah in enumerate(line[::n])]
?解决这个问题,这是一个很好的答案:)。
,blah
为何以及为什么有必要吗?我注意到我可以blah
用任何字母字符代替,但不能用数字代替,并且不能删除blah
or或逗号。我的编辑建议在,
:s 之后添加空格
enumerate
返回两个可迭代对象,因此您需要两个位置放置它们。但是在这种情况下,您实际上不需要任何东西的第二个可迭代对象。
blah
我更喜欢使用下划线或双下划线,请参阅:stackoverflow.com/questions/5893163/...
一个短字符串的简单递归解决方案:
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)
,它更明确地说明了递归方法中的典型分而治之模式(尽管实际上没有必要这样做)
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
这可以通过简单的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']