一直在抓我的头。如何删除嵌套列表的第n个索引?
我的格式为嵌套列表:
((value1, value2, value3), (value1, value2, value3), ... (value1, value2, value3))
现在我试图得到它归结为:
((value1, value2), (value1, value2), ... (value1, value2))
总之,试图消除每个嵌套的第三元素名单。
这是可能的Python直接?
一直在抓我的头。如何删除嵌套列表的第n个索引?
我的格式为嵌套列表:
((value1, value2, value3), (value1, value2, value3), ... (value1, value2, value3))
现在我试图得到它归结为:
((value1, value2), (value1, value2), ... (value1, value2))
总之,试图消除每个嵌套的第三元素名单。
这是可能的Python直接?
为此,您可以简单地用一个列表理解:
>>> 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)]
+1不使用切片 – unkulunkulu 2013-04-25 15:49:40
您的使用有些奇怪>>> – ascobol 2013-04-25 15:53:06
@unkulunkulu:然而,对于序列中的每个子列表,切片将比拆包和重新打包更快。 :-) – 2013-04-25 15:56:32
使用列表理解:
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
你从我那里得到+1。然而,在这种情况下,请选择看起来更好的,而不是更快的 - 担心这肯定会让人担心过早的优化。 – Yuushi 2013-04-25 16:18:32
@Yuushi:通常情况下,我会同意你的看法,但是在列表解析中你要小心。这*是循环的内部部分,只是意识到预先技术之间的差异有所帮助。此外,切片与拆包/重新包装几乎不可读,是吗? – 2013-04-25 16:19:48
对不起,我没有暗示它不太可读(说实话它可能稍微有些可读性),只是除非这真的成为一个探查器的瓶颈,我不会担心它。但进行分析对于何时出现问题肯定有用。 – Yuushi 2013-04-25 16:22:32
>>> 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))
使用地图:
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))
试试这个:
[a[ :-1] for a in b]
或者这样:
[a[:n]+a[n+1:] for a in b]
x = [(1, 2, 3), (1, 2, 3), (1, 2, 3)]
>>> [i[:2] for i in x ]
[(1,2), (1,2),(1,2)]
你在这里有元组;列表有'[]'方括号。 – 2013-04-25 15:48:13
你想要做到这一点或获得一个单独的实例吗? – bereal 2013-04-25 15:49:22