【发布时间】:2011-11-29 23:07:08
【问题描述】:
我有一个带有数字的字符串 - digit = "7316717"
现在我想以这样的方式拆分字符串,即输出是一次 3 位数的移动窗口。所以我得到 -
["731", "316", "167", "671", "717"]
方法是怎样的?直接的方法是放入for循环并迭代。但我觉得一些内置的 python 字符串函数可以用更少的代码做到这一点。知道这样的方法吗?
【问题讨论】:
我有一个带有数字的字符串 - digit = "7316717"
现在我想以这样的方式拆分字符串,即输出是一次 3 位数的移动窗口。所以我得到 -
["731", "316", "167", "671", "717"]
方法是怎样的?直接的方法是放入for循环并迭代。但我觉得一些内置的 python 字符串函数可以用更少的代码做到这一点。知道这样的方法吗?
【问题讨论】:
itertools examples 提供了 window 函数来做这件事:
from itertools import islice
def window(seq, n=2):
"Returns a sliding window (of width n) over data from the iterable"
" s -> (s0,s1,...s[n-1]), (s1,s2,...,sn), ... "
it = iter(seq)
result = tuple(islice(it, n))
if len(result) == n:
yield result
for elem in it:
result = result[1:] + (elem,)
yield result
示例用法:
>>> ["".join(x) for x in window("7316717", 3)]
['731', '316', '167', '671', '717']
【讨论】:
window 函数(取自链接文档)是如何使用islice() 创建通用window 函数的示例。
itertoolsrecipes 中有一个更令人愉悦的代码,称为 pairwise。
pairwise 确实看起来更令人愉快,但它被硬编码为 2 的滑动窗口(因此 pairwise)。我想它可以被参数化,但它可能不再那么令人愉快了,因为它使用tee 和zip 它可能不如window 配方那么有效。
tee 和 izip 是用 C 语言编写的,因此速度非常快。愉快是个人品味的问题,我认为:)
>>> s = "7316717"
>>> [s[i:i+3] for i in range(len(s)-2)]
['731', '316', '167', '671', '717']
【讨论】:
itertools docs中有一个很好的食谱pairwise。
对组中的n 元素进行了一些现代化改造,我编写了以下代码:
from itertools import tee, izip
def window(iterable, n):
els = tee(iterable, n)
for i, el in enumerate(els):
for _ in xrange(i):
next(el, None)
return izip(*els)
print(["".join(i) for i in window("2316515618", 3)])
Python 2.7
【讨论】:
tee 和next。 +1
enumerate 版本。但是,您应该多花一些空间,也许使用xrange 而不是range。
digit = "7316717"
digit_sets = [digit[i:i+3] for i in range(len(digit)-2)]
【讨论】: