我的问题是,我有一个如下列表:
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)
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)
请注意,这会返回生成器而不是列表,因此无法编入索引.
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)