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

Ric*_*ard 14 python list

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

someList = [[0,1,2],[3,4,5],[6,7,8]]
Run Code Online (Sandbox Code Playgroud)

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

我知道我可以这样做:

newList = []
for entry in someList:
    newList.append(entry[0])
Run Code Online (Sandbox Code Playgroud)

newList将在哪里:

[0, 3, 6]
Run Code Online (Sandbox Code Playgroud)

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

newList = someList[:][0] 
Run Code Online (Sandbox Code Playgroud)

编辑:

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

Kat*_*iel 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
>>>
Run Code Online (Sandbox Code Playgroud)

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

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

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

>>> foo.transpose()
array([[0, 3, 6],
       [1, 4, 7],
       [2, 5, 8]])
Run Code Online (Sandbox Code Playgroud)

...使用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.]])
Run Code Online (Sandbox Code Playgroud)

..do高效线性代数...

>>> 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]]))
Run Code Online (Sandbox Code Playgroud)

......基本上做Matlab可以做的任何事情.

  • @jellybean:我怀疑...... numpy真的很好地优化了.我认为可以说一个简单的逐列切片不会读取整个矩阵.(虽然我当然可能错了,但我不知道C实现细节.)事实上,我认为`numpy`应该用更大的列表执行*更好*,因为Python的本地`list`类型的开销开始了加起来.但当然,只有一种方法可以找到答案! (2认同)

rec*_*ive 10

列表理解的完美案例:

[sublist[0] for sublist in someList]
Run Code Online (Sandbox Code Playgroud)

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

(sublist[0] for sublist in someList)
Run Code Online (Sandbox Code Playgroud)

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


Joh*_*rra 8

zip(*someList)[0]
Run Code Online (Sandbox Code Playgroud)

编辑:

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

from itertools import izip
izip(*someList).next()
Run Code Online (Sandbox Code Playgroud)

为了更好的表现.

一些时间分析:

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
Run Code Online (Sandbox Code Playgroud)

所以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
Run Code Online (Sandbox Code Playgroud)