获取具有给定索引的Python列表的子列表?

bec*_*cko 25 python list python-2.7

我有一个Python列表,比方说a = [0,1,2,3,4,5,6].我也有一份指数清单b = [0,2,4,5].如何获取a带索引的元素列表b

Chr*_*ian 35

您可以使用列表推导来获取该列表:

c = [a[index] for index in b]
print c
Run Code Online (Sandbox Code Playgroud)

这相当于:

c= []
for index in b:
    c.append(a[index])
print c
Run Code Online (Sandbox Code Playgroud)

输出:

[0,2,4,5]
Run Code Online (Sandbox Code Playgroud)

注意:

请记住,这some_list[index]是用于访问list特定索引中的元素的表示法.


che*_*ner 23

有些不同...

>>> a = range(7)
>>> b = [0,2,4,5]
>>> import operator
>>> operator.itemgetter(*b)(a)
(0, 2, 4, 5)
Run Code Online (Sandbox Code Playgroud)

itemgetter函数将一个或多个键作为参数,并返回一个函数,该函数将返回参数中给定键的项.所以在上面,我们创建了一个函数,它将返回索引0,索引2,索引4和索引5处的项,然后将该函数应用于a.

它看起来比同等列表理解要快得多

In [1]: import operator

In [2]: a = range(7)

In [3]: b = [0,2,4,5]

In [4]: %timeit operator.itemgetter(*b)(a)
1000000 loops, best of 3: 388 ns per loop

In [5]: %timeit [ a[i] for i in b ]
1000000 loops, best of 3: 415 ns per loop

In [6]: f = operator.itemgetter(*b)

In [7]: %timeit f(a)
10000000 loops, best of 3: 183 ns per loop
Run Code Online (Sandbox Code Playgroud)

至于为什么itemgetter更快,理解必须执行额外的Python字节代码.

In [3]: def f(a,b): return [a[i] for i in b]

In [4]: def g(a,b): return operator.itemgetter(*b)(a)

In [5]: dis.dis(f)
  1           0 BUILD_LIST               0
              3 LOAD_FAST                1 (b)
              6 GET_ITER
        >>    7 FOR_ITER                16 (to 26)
             10 STORE_FAST               2 (i)
             13 LOAD_FAST                0 (a)
             16 LOAD_FAST                2 (i)
             19 BINARY_SUBSCR
             20 LIST_APPEND              2
             23 JUMP_ABSOLUTE            7
        >>   26 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)

虽然itemgetter是在C中实现的单个调用:

In [6]: dis.dis(g)
  1           0 LOAD_GLOBAL              0 (operator)
              3 LOAD_ATTR                1 (itemgetter)
              6 LOAD_FAST                1 (b)
              9 CALL_FUNCTION_VAR        0
             12 LOAD_FAST                0 (a)
             15 CALL_FUNCTION            1
             18 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)


iCo*_*dez 8

如果您是函数式编程的粉丝,可以使用maplist.__getitem__:

>>> a = [0,1,2,3,4,5,6]
>>> b = [0,2,4,5]
>>> map(a.__getitem__, b)
[0, 2, 4, 5]
>>>
Run Code Online (Sandbox Code Playgroud)

列表理解方法在Python中更规范,但......


Bri*_*ian 5

许多提议的解决方案将产生一个KeyErrorifb包含一个不存在的索引a。如果需要,以下将跳过无效索引。

>>> b = [0,2,4,5]
>>> a = [0,1,2,3,4,5,6]
>>> [x for i,x in enumerate(a) if i in b]
[0, 2, 4, 5]
>>> b = [0,2,4,500]
>>> [x for i,x in enumerate(a) if i in b]
[0, 2, 4]
Run Code Online (Sandbox Code Playgroud)

enumerate产生索引,值对的元组。由于我们同时拥有项目及其索引,我们可以检查 b 中是否存在索引