Python 列表的切片模式
我有一个列表,其中有未定义数量的元素:Python 列表的切片模式,python,list,design-patterns,slice,Python,List,Design Patterns,Slice,我有一个列表,其中有未定义数量的元素: l1 = [a, b, c, d ...] 我需要创建一个列表,以便: l2 = [[a,a],[a,b],[b,b],[b,c],[c,c],[c,d],[d,d],[d,e],...] 现在,为了获得l2,我做了以下工作: l1 = sorted(l1*4)[1:-1] l2 = [l1[x:x+2] for x in xrange(0,len(l1),2)] 它可以工作,但我不喜欢它,因为如果l1中的元素数量非常大,那么此代码将非常消耗内存(*
l1 = [a, b, c, d ...]
我需要创建一个列表,以便:
l2 = [[a,a],[a,b],[b,b],[b,c],[c,c],[c,d],[d,d],[d,e],...]
现在,为了获得l2,我做了以下工作:
l1 = sorted(l1*4)[1:-1]
l2 = [l1[x:x+2] for x in xrange(0,len(l1),2)]
它可以工作,但我不喜欢它,因为如果l1中的元素数量非常大,那么此代码将非常消耗内存(*4)和时间(排序)。关于如何实现这一点,您有什么建议吗?因为在内存使用方面,您需要一个最佳的代码,最好的方法是使用生成器,在这种情况下,您可以使用
itertools
模块:
>>> def pair_creator(iterator):
... pairs = chain.from_iterable((repeat(i,2) for i in iterator))
... forward, pairs = tee(pairs)
... next(forward)
... return zip(pairs,forward)
这里您只需要创建一个迭代器,其中包含前面项目的重复对
new = chain.from_iterable((repeat(i,2) for i in l1))
然后使用tee
从当前迭代器创建两个独立的迭代器,然后使用next
使用其中一个迭代器的第一项。他们使用zip
(izip
在Python2.X中)获得正确的列
演示:
假设初始列表是有序的:
l1 = [a, b, c, d ...]
l2 = []
for ii, x in enumerate(l1[:-1]):
l2.append([x,x])
l2.append([x,l1[ii+1])
l2.append([l1[-1],l1[-1]) # last element
以下是您的功能:
fn = lambda xs: concatMap(f, zip(xs, xs[1:]))
下面是我如何使用列表理解:
In [46]: from itertools import izip, islice
In [47]: l1 = ['a', 'b', 'c', 'd', 'e']
In [48]: l2=[x for (a,b) in izip(l1, islice(l1, 1,None)) for x in ([a,a],[a,b])] ; l2 += [[b,b]]
In [49]: l2
Out[49]:
[['a', 'a'],
['a', 'b'],
['b', 'b'],
['b', 'c'],
['c', 'c'],
['c', 'd'],
['d', 'd'],
['d', 'e'],
['e', 'e']]
是的,我更喜欢列表!但是,在接受之前:列表应该以['e','e']结尾。你是如何做到的?在末尾添加
l2+=[[b,b]]
。查看我最近的编辑。
fn = lambda xs: concatMap(f, zip(xs, xs[1:]))
In [46]: from itertools import izip, islice
In [47]: l1 = ['a', 'b', 'c', 'd', 'e']
In [48]: l2=[x for (a,b) in izip(l1, islice(l1, 1,None)) for x in ([a,a],[a,b])] ; l2 += [[b,b]]
In [49]: l2
Out[49]:
[['a', 'a'],
['a', 'b'],
['b', 'b'],
['b', 'c'],
['c', 'c'],
['c', 'd'],
['d', 'd'],
['d', 'e'],
['e', 'e']]