2013-04-25 43 views
0

一直在抓我的头。如何删除嵌套列表的第n个索引?

我的格式为嵌套列表:

((value1, value2, value3), (value1, value2, value3), ... (value1, value2, value3)) 

现在我试图得到它归结为:

((value1, value2), (value1, value2), ... (value1, value2)) 

总之,试图消除每个嵌套的第三元素名单。

这是可能的Python直接?

+0

你在这里有元组;列表有'[]'方括号。 – 2013-04-25 15:48:13

+0

你想要做到这一点或获得一个单独的实例吗? – bereal 2013-04-25 15:49:22

回答

6

为此,您可以简单地用一个列表理解:

>>> x = [(1, 2, 3), (1, 2, 3), (1, 2, 3)] 
>>> x = [(a, b) for (a, b, c) in x] 
[(1, 2), (1, 2), (1, 2)] 
+0

+1不使用切片 – unkulunkulu 2013-04-25 15:49:40

+1

您的使用有些奇怪>>> – ascobol 2013-04-25 15:53:06

+0

@unkulunkulu:然而,对于序列中的每个子列表,切片将比拆包和重新打包更快。 :-) – 2013-04-25 15:56:32

6

使用列表理解:

outerlist = [sublist[:-1] for sublist in outerlist] 

这使用切片删除每个子列表包含的最后一个元素。

以上创建了list()而不是tuple();以下将再次创建一个元组:

outertuple = tuple(sublist[:-1] for sublist in outertuple) 

切片的子表需要操作码比拆包并重新包装一个元组,得到的结果给你更快的少。

使用演示元组:

>>> outertuple = ((1, 2, 3), (4, 5, 6), (7, 8, 9)) 
>>> tuple(sublist[:-1] for sublist in outertuple) 
((1, 2), (4, 5), (7, 8)) 

演示使用列表:

>>> outerlist = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] 
>>> [sublist[:-1] for sublist in outerlist] 
[[1, 2], [4, 5], [7, 8]] 

最后但并非最不重要的,在列表解析的内部循环字节码反汇编表明,切片使用较少的操作码比开箱和重新包装:

>>> import dis 
>>> def foo(x): return [sublist[:-1] for sublist in x] 
... 
>>> def bar(x): return [(a, b) for (a, b, c) in x] 
... 
>>> dis.dis(foo) 
    1   0 BUILD_LIST    0 
       3 LOAD_FAST    0 (x) 
       6 GET_ITER    
     >> 7 FOR_ITER    16 (to 26) 
      10 STORE_FAST    1 (sublist) 
      13 LOAD_FAST    1 (sublist) 
      16 LOAD_CONST    1 (-1) 
      19 SLICE+2    
      20 LIST_APPEND    2 
      23 JUMP_ABSOLUTE   7 
     >> 26 RETURN_VALUE   
>>> dis.dis(bar) 
    1   0 BUILD_LIST    0 
       3 LOAD_FAST    0 (x) 
       6 GET_ITER    
     >> 7 FOR_ITER    27 (to 37) 
      10 UNPACK_SEQUENCE   3 
      13 STORE_FAST    1 (a) 
      16 STORE_FAST    2 (b) 
      19 STORE_FAST    3 (c) 
      22 LOAD_FAST    1 (a) 
      25 LOAD_FAST    2 (b) 
      28 BUILD_TUPLE    2 
      31 LIST_APPEND    2 
      34 JUMP_ABSOLUTE   7 
     >> 37 RETURN_VALUE   

11与14操作码。这是一个额外的UNPACK_SEQUENCE和另外两个STORE_FAST操作码,以及BUILD_TUPLE操作码与SLICE+2

这些差异使得拆包,包装相当慢一点:

>>> import timeit 
>>> test = [(42, 69, 180) for _ in xrange(1000)] 
>>> timeit.timeit('f(x)', 'from __main__ import test as x, foo as f', number=10000) 
1.1722910404205322 
>>> timeit.timeit('f(x)', 'from __main__ import test as x, bar as f', number=10000) 
1.6375460624694824 
+0

你从我那里得到+1。然而,在这种情况下,请选择看起来更好的,而不是更快的 - 担心这肯定会让人担心过早的优化。 – Yuushi 2013-04-25 16:18:32

+0

@Yuushi:通常情况下,我会同意你的看法,但是在列表解析中你要小心。这*是循环的内部部分,只是意识到预先技术之间的差异有所帮助。此外,切片与拆包/重新包装几乎不可读,是吗? – 2013-04-25 16:19:48

+0

对不起,我没有暗示它不太可读(说实话它可能稍微有些可读性),只是除非这真的成为一个探查器的瓶颈,我不会担心它。但进行分析对于何时出现问题肯定有用。 – Yuushi 2013-04-25 16:22:32

1
nested_list= [[1,2,3],[4,5,6]] 

for regular_list in nested_list: 
    del regular_list[2] 
+0

为什么downvote?有用。遍历列表可以获得子列表,而del列表名[indexyouwantgone]可以删除给定的元素。他不一定说他想删除最后一个元素。 – BWStearns 2013-04-25 15:52:23

+0

也许是因为OP似乎有元组,它们是不可变的? – 2013-04-25 15:53:22

+0

如果他想改变它,他可能不应该使用元组。 – BWStearns 2013-04-25 15:56:13

2
>>> a = ((1,2,3), (4,5,6), (7,8,9)) 
>>> a = tuple([(x1, x2) for (x1, x2, x3) in a]) 
>>> a 
((1, 2), (4, 5), (7, 8)) 
0

使用地图:

l = [[0,1,2], [1,2,3]] 
print map(lambda l : l[:-1], l) 
# Outputs [[0, 1], [1, 2]] 

鉴于所有子列表的长度都是3。

如果你想这样的元组:

l = ((0,1,2), (1,2,3)) 
print tuple(map(lambda l : l[:-1], l)) 
# Outputs ((0, 1), (1, 2)) 
1

试试这个:

[a[ :-1] for a in b] 

或者这样:

[a[:n]+a[n+1:] for a in b] 
0
x = [(1, 2, 3), (1, 2, 3), (1, 2, 3)] 
>>> [i[:2] for i in x ] 

[(1,2), (1,2),(1,2)]