我有一个列表,其中有一些未定义的元素:
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 )和时间(已排序)消费。你有关于如何做到这一点的任何提示吗?
答案 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:]))