我有一个字符串,我需要分成两个字母的部分。例如,'ABCDXY'
应该变为['AB', 'CD', 'XY']
。奇数个字符的行为可能完全是任意的(我会提前检查长度)。
有没有办法在没有丑陋的循环的情况下做到这一点?
答案 0 :(得分:21)
>>> [s[i:i + 2] for i in range(0, len(s), 2)]
['AB', 'CD', 'XY']
答案 1 :(得分:16)
使用正则表达式!
>>> import re
>>> s = "ABCDXYv"
>>> re.findall(r'.{1,2}',s,re.DOTALL)
['AB', 'CD', 'XY', 'v']
我知道已经有一段时间了,但我回到了这一点,对于哪种方法更好而感到好奇;我的:r'.{1,2}'
或Jon的r'..?'
。从表面上看,Jon看起来好多了,我觉得它会比我快得多,但我很惊讶地发现,所以我想我会分享:
>>> import timeit
>>> timeit.Timer("re.findall(r'.{1,2}', 'ABCDXYv')", setup='import re').repeat()
[1.9064299485802252, 1.8369554649334674, 1.8548105833383772]
>>> timeit.Timer("re.findall(r'..?', 'ABCDXYv')", setup='import re').repeat()
[1.9142223469651611, 1.8670038395145383, 1.85781945659771]
这表明确实r'.{1,2}'
是更好/更快的选择。 (但只是略微)
答案 2 :(得分:2)
你可以尝试:
s = 'ABCDEFG'
r = [s[i:i+2] for i in xrange(0, len(s), 2)]
# r is ['AB', 'CD', 'EF', 'G']
更新2
如果你不关心奇数字符,你可以使用正则表达式(避免循环):
s = 'ABCDEFG'
r = re.compile('(..)').findall(s)
# r is ['AB', 'CD', 'EF']
答案 3 :(得分:1)
完美的Pythonic没有什么难看的:
string = 'ABCDXY'
[string[i:i+2] for i in xrange(0, len(string), 2)]
您还可以使用以下内容(来自 - http://docs.python.org/library/itertools.html):
def grouper(n, iterable, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)
(这取决于你如何看待它 - 可能会也可能不会使用'循环';)
或类似的东西:
re.findall('..?', string)
答案 4 :(得分:0)
又一个解决方案,这个解决方案建立在zip
和切片步幅:
map(''.join, itertools.izip_longest(mystr[::2], mystr[1::2], fillvalue=''))
它确实处理奇数长度输入。
答案 5 :(得分:0)
这是另一种没有显式循环的解决方案(尽管@Emmanuel's answer is the most appropriate for your question):
s = 'abcdef'
L = zip(s[::2], s[1::2])
# -> [('a', 'b'), ('c', 'd'), ('e', 'f')]
获取字符串:
print map(''.join, L)
# ['ab', 'cd', 'ef']
在必要时使用list()
在Python 3上进行换行。