在Python中提取每个子列表的第一项

qf9go6mv  于 2023-05-16  发布在  Python
关注(0)|答案(9)|浏览(182)

我想知道什么是最好的方法来提取列表列表中每个子列表的第一项,并将其附加到一个新的列表。如果我有:

lst = [[a,b,c], [1,2,3], [x,y,z]]

然后,我想取出a1x,并从中创建一个单独的列表。
我试过:

lst2.append(x[0] for x in lst)
qvtsj1bj

qvtsj1bj1#

使用列表解析:

>>> lst = [['a','b','c'], [1,2,3], ['x','y','z']]
>>> lst2 = [item[0] for item in lst]
>>> lst2
['a', 1, 'x']
iqih9akk

iqih9akk2#

你可以使用zip:

>>> lst=[[1,2,3],[11,12,13],[21,22,23]]
>>> zip(*lst)[0]
(1, 11, 21)

或者,Python 3中zip不生成列表:

>>> list(zip(*lst))[0]
(1, 11, 21)

或者

>>> next(zip(*lst))
(1, 11, 21)

或者,(我的最爱)使用numpy:

>>> import numpy as np
>>> a=np.array([[1,2,3],[11,12,13],[21,22,23]])
>>> a
array([[ 1,  2,  3],
       [11, 12, 13],
       [21, 22, 23]])
>>> a[:,0]
array([ 1, 11, 21])
dw1jzc5e

dw1jzc5e3#

遇到了同样的问题,并对每个解决方案的性能感到好奇。
下面是%timeit

import numpy as np
lst = [['a','b','c'], [1,2,3], ['x','y','z']]

第一个numpy-way,转换数组:

%timeit list(np.array(lst).T[0])
4.9 µs ± 163 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

使用列表解析的完全原生(如@alecxe所解释的):

%timeit [item[0] for item in lst]
379 ns ± 23.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

另一种使用zip的原生方式(如@dawg所解释的):

%timeit list(zip(*lst))[0]
585 ns ± 7.26 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

第二种 numpy 方式。@dawg也解释道:

%timeit list(np.array(lst)[:,0])
4.95 µs ± 179 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

令人惊讶的是(好吧,至少对我来说)使用列表理解的原生方式是最快的,比numpy-way快了大约10倍。在没有最终list的情况下运行两个numpy-way可以节省大约1 µs,这仍然是10倍的差异。
请注意,当我用对len的调用包围每个代码片段时,为了确保Generators运行到最后,计时保持不变。

o4hqfura

o4hqfura4#

Python包含一个名为itemgetter的函数,用于返回列表中特定索引处的项:

from operator import itemgetter

向itemgetter()函数传递要检索的项的索引。要检索第一个项,可以使用itemgetter(0)。重要的是要理解itemgetter(0)本身返回一个函数。如果你传递一个列表给那个函数,你会得到特定的项:

itemgetter(0)([10, 20, 30]) # Returns 10

当你将它与map()结合使用时,这是很有用的,map()将一个函数作为它的第一个参数,一个列表(或任何其他可迭代对象)作为第二个参数。它返回在可迭代对象中的每个对象上调用函数的结果:

my_list = [['a', 'b', 'c'], [1, 2, 3], ['x', 'y', 'z']]
list(map(itemgetter(0), my_list)) # Returns ['a', 1, 'x']

请注意,map()返回一个生成器,因此将结果传递给list()以获得实际的列表。总而言之,你的任务可以这样完成:

lst2.append(list(map(itemgetter(0), lst)))

这是使用列表解析的另一种方法,选择哪种方法在很大程度上取决于上下文、可读性和偏好。
更多信息:https://docs.python.org/3/library/operator.html#operator.itemgetter

p5cysglq

p5cysglq5#

你的代码几乎正确。唯一的问题是列表解析的用法。
如果您使用like:(x[0] for x in lst),它返回一个生成器对象。如果您使用like:[x[0] for x in lst],它返回一个列表。
当您将列表解析输出追加到列表时,列表解析的输出是列表的单个元素。

lst = [["a","b","c"], [1,2,3], ["x","y","z"]]
lst2 = []
lst2.append([x[0] for x in lst])
print lst2[0]

lst2 = 'a',1,'x'
lst2[0] = ['a',1,'x']
请让我知道如果我错了。

l5tcr1uw

l5tcr1uw6#

lst = [['a','b','c'], [1,2,3], ['x','y','z']]
outputlist = []
for values in lst:
    outputlist.append(values[0])

print(outputlist)

输出:['a', 1, 'x']

deikduxw

deikduxw7#

你说你有一个现有的名单。所以我同意你的说法。

>>> lst1 = [['a','b','c'], [1,2,3], ['x','y','z']]
>>> lst2 = [1, 2, 3]

现在,您正在将生成器对象追加到第二个列表中。

>>> lst2.append(item[0] for item in lst)
>>> lst2
[1, 2, 3, <generator object <genexpr> at 0xb74b3554>]

但你可能希望它是一个第一项的列表

>>> lst2.append([item[0] for item in lst])
>>> lst2
[1, 2, 3, ['a', 1, 'x']]

现在,我们将第一个项目的列表附加到现有列表中。如果你想将项目themeselves,而不是它们的列表添加到现有的项目中,你可以使用list.extend。在这种情况下,我们不必担心添加生成器,因为extend将使用该生成器添加从那里获得的每个项,以扩展当前列表。

>>> lst2.extend(item[0] for item in lst)
>>> lst2
[1, 2, 3, 'a', 1, 'x']

>>> lst2 + [x[0] for x in lst]
[1, 2, 3, 'a', 1, 'x']
>>> lst2
[1, 2, 3]

https://docs.python.org/3.4/tutorial/datastructures.html#more-on-listshttps://docs.python.org/3.4/tutorial/datastructures.html#list-comprehensions

qlckcl4x

qlckcl4x8#

您可以将列表列表中的第一个值提取到新列表中,如下所示:

list_of_lists = [
    ['John', 'Anna'], [36, 24], ['Male', 'Female']
] 
           
new_list = [list[0] for list in list_of_lists] # Here

print(new_list) # ['John', 36, 'Male']
5n0oy7gb

5n0oy7gb9#

另一个我可以建议的答案是

lst = [['a','b','c'], [1,2,3], ['x','y','z']]
new_lst=[lst[0][0],lst[1][0],lst[2][0]]
print(new_lst)

输出如下
['a',1,'x']
希望这有帮助!谢谢!

相关问题