python multidimensional list ..如何抓住一个维度?

时间:2010-09-09 13:10:13

标签: python list

我的问题是,我有一个如下列表:

someList = [[0,1,2],[3,4,5],[6,7,8]]

我如何获得每个子列表的第一个条目?

我知道我可以这样做:

newList = []
for entry in someList:
    newList.append(entry[0])

其中newList将是:

[0, 3, 6]

但有没有办法做一些事情:

newList = someList[:][0] 

编辑:

效率非常令人担忧。我实际上正在浏览一个包含超过300000个条目的列表

3 个答案:

答案 0 :(得分:17)

编辑:这是一些实际的数字! izip,列表理解和numpy这样做的方式速度大致相同。

# zip
>>> timeit.timeit( "newlist = zip(*someList)[0]", setup = "someList = [range(1000000), range(1000000), range(1000000)]", number = 10 )
1.4984046398561759

# izip
>>> timeit.timeit( "newlist = izip(*someList).next()", setup = "someList = range(1000000), range(1000000), range(1000000)]; from itertools import izip", number = 10 )
2.2186223645803693e-05

# list comprehension
>>> timeit.timeit( "newlist = [li[0] for li in someList]", setup = "someList = [range(1000000), range(1000000), range(1000000)]", number = 10 )
1.4677040212518477e-05

# numpy
>>> timeit.timeit( "newlist = someList[0,:]", setup = "import numpy as np; someList = np.array([range(1000000), range(1000000), range(1000000)])", number = 10 )
6.6217344397045963e-05
>>>

对于像这样的大型数据结构,你应该使用numpy,它在C中实现一个数组类型,因此效率更高。它还提供了您想要的所有矩阵操作。

>>> import numpy as np
>>> foo = np.array([[0,1,2],[3,4,5],[6,7,8]])
>>> foo[:,0]
array([0, 3, 6])

你也可以转置......

>>> foo.transpose()
array([[0, 3, 6],
       [1, 4, 7],
       [2, 5, 8]])

...使用n维数组...

>>> foo = np.zeros((3,3,3))
>>> foo
array([[[ 0.,  0.,  0.],
        [ 0.,  0.,  0.],
        [ 0.,  0.,  0.]],

       [[ 0.,  0.,  0.],
        [ 0.,  0.,  0.],
        [ 0.,  0.,  0.]],

       [[ 0.,  0.,  0.],
        [ 0.,  0.,  0.],
        [ 0.,  0.,  0.]]])
>>> foo[0,...]
array([[ 0.,  0.,  0.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  0.]])

..做高效的线性代数......

>>> foo = no.ones((3,3))
>>> np.linalg.qr(foo)
(array([[-0.57735027,  0.81649658,  0.        ],
       [-0.57735027, -0.40824829, -0.70710678],
       [-0.57735027, -0.40824829,  0.70710678]]), array([[ -1.73205081e+00,  -1.
73205081e+00,  -1.73205081e+00],
       [  0.00000000e+00,  -1.57009246e-16,  -1.57009246e-16],
       [  0.00000000e+00,   0.00000000e+00,   0.00000000e+00]]))

...基本上做anything that Matlab can

答案 1 :(得分:10)

list comprehension的完美案例:

[sublist[0] for sublist in someList]

由于效率是一个主要问题,这将比zip方法快得多。根据您对结果所做的工作,您可以通过使用生成器表达式方法获得更高的效率:

(sublist[0] for sublist in someList)

请注意,这会返回生成器而不是列表,因此无法将其编入索引。

答案 2 :(得分:8)

zip(*someList)[0]

编辑:

回应递归的评论:人们也可以使用

from itertools import izip
izip(*someList).next()

以获得更好的表现。

一些时间分析:

python -m timeit "someList = [range(1000000), range(1000000), range(1000000)]; newlist = zip(*someList)[0]"
10 loops, best of 3: 498 msec per loop
python -m timeit "someList = [range(1000000), range(1000000), range(1000000)]; from itertools import izip; newlist = izip(*someList).next()"
10 loops, best of 3: 111 msec per loop
python -m timeit "someList = [range(1000000), range(1000000), range(1000000)]; newlist = [li[0] for li in someList]"
10 loops, best of 3: 110 msec per loop

所以izip和列表理解在同一个联盟中发挥作用。

当你需要一个非0的索引时,列表理解会更灵活,而且更明确。

EDIT2:

即使是numpy解决方案也不是那么快(但我可能选择了一个非代表性的例子):

python -m timeit "import numpy as np; someList = np.array([range(1000000), range(1000000), range(1000000)]); newList = someList[:,0]"
10 loops, best of 3: 551 msec per loop