列表的切片模式

时间:2015-12-22 15:33:15

标签: 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中的元素数量非常大,那么这段代码将是非常大的内存( * 4 )和时间(已排序)消费。你有关于如何做到这一点的任何提示吗?

4 个答案:

答案 0 :(得分: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']]

答案 1 :(得分:0)

由于在内存使用方面需要最佳代码,最好的方法是使用生成器,在这种情况下,您可以使用>>> 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从当前迭代器创建2个独立迭代器,然后使用use zip来使用其中一个的第一项,他们使用izip>>> l1 = range(10) >>> pair_creator(l1) [(0, 0), (0, 1), (1, 1), (1, 2), (2, 2), (2, 3), (3, 3), (3, 4), (4, 4), (4, 5), (5, 5), (5, 6), (6, 6), (6, 7), (7, 7), (7, 8), (8, 8), (8, 9), (9, 9)] >>> 在python中2.X)获得正确的列。

演示:

{{1}}

答案 2 :(得分:0)

假设初始列表是有序的:

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

答案 3 :(得分:0)

f         = lambda (x, y): [[x, x], [x, y]]
concat    = lambda xs: sum(xs, [])
concatMap = lambda f, xs: concat(map(f, xs))

这是你的功能:

fn = lambda xs: concatMap(f, zip(xs, xs[1:]))