2012-05-04 31 views
4

我想从一个数据结构去像所有列:双人除了第一个和最后一个

[[0, 12, 25, 45, 65, 100], 
[0, 0, 0, 255, 255, 255], 
[0, 0, 255, 255, 0, 0], 
[255, 255, 0, 0, 0, 0]] 

到:

[[0, 12, 12, 25, 25, 45, 45, 65, 65, 100], 
[0, 0, 0, 0, 0, 255, 255, 255, 255, 255], 
[0, 0, 0, 255, 255, 255, 255, 0, 0, 0], 
[255, 255, 255, 0, 0, 0, 0, 0, 0, 0]] 

(所有列,除了第一个和最后一个一个重复)。

我有以下列表理解的作品:

[[l[0]] + [x for sl in [[i, i] for i in l[1:-1]] for x in sl] + [l[-1]] for l in list_of_lists] 

,但我不知道是否有写这更优雅,更可读的方式。

回答

2

我想知道是否有更优雅和更可读的方式来写这个。

我想你还应该考虑“更具可读性”并不一定意味着“可以将它塞进一行吗?”。它通常意味着更直接,更直接的迭代代码。也许你会发现这个功能更具可读性:

>>> def double_middle_items(l): 
     if len(l) < 2: 
      raise ValueError("there must be at least two items in l") 

     result = [l[0]] 
     for item in l[1:-1]: 
      result.append(item) 
      result.append(item) 
     result.append(l[-1]) 
     return result 

>>> double_middle_items([1,2,3,4,5]) 
[1, 2, 2, 3, 3, 4, 4, 5] 

然后你的代码变得非常简单:

>>> [double_middle_items(l) for l in list_of_lists] 
2
>>> from itertools import chain 
>>> data = [[0, 12, 25, 45, 65, 100], [0, 0, 0, 255, 255, 255], [0, 0, 255, 255, 0, 0], [255, 255, 0, 0, 0, 0]] 
>>> [list(chain.from_iterable(zip(l,l[1:]))) for l in data] 
[[0, 12, 12, 25, 25, 45, 45, 65, 65, 100], [0, 0, 0, 0, 0, 255, 255, 255, 255, 255], [0, 0, 0, 255, 255, 255, 255, 0, 0, 0], [255, 255, 255, 0, 0, 0, 0, 0, 0, 0]] 
2

鉴于你的列表,

>>> spam=[[0, 12, 25, 45, 65, 100], 
[0, 0, 0, 255, 255, 255], 
[0, 0, 255, 255, 0, 0], 
[255, 255, 0, 0, 0, 0]] 

你可以链的复制列表中的每个元素

>>> from itertools import repeat,chain 
>>> [list(chain(*([i]*2 for i in r)))[1:-1] for r in spam] 
[[0, 0, 12, 12, 25, 25, 45, 45, 65, 65, 100, 100], [0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255], [0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0], [255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0]] 

或使用重复

>>> [list(chain(*(repeat(i,2) for i in r)))[1:-1] for r in spam] 
相关问题