我想知道什么是最好的方法来提取列表列表中每个子列表的第一项,并将其附加到一个新的列表。如果我有:
lst = [[a,b,c], [1,2,3], [x,y,z]]
然后,我想取出a、1和x,并从中创建一个单独的列表。我试过:
a
1
x
lst2.append(x[0] for x in lst)
qvtsj1bj1#
使用列表解析:
>>> lst = [['a','b','c'], [1,2,3], ['x','y','z']] >>> lst2 = [item[0] for item in lst] >>> lst2 ['a', 1, 'x']
iqih9akk2#
你可以使用zip:
>>> lst=[[1,2,3],[11,12,13],[21,22,23]] >>> zip(*lst)[0] (1, 11, 21)
或者,Python 3中zip不生成列表:
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])
dw1jzc5e3#
遇到了同样的问题,并对每个解决方案的性能感到好奇。下面是%timeit:
%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运行到最后,计时保持不变。
list
len
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
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']请让我知道如果我错了。
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']
['a', 1, 'x']
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
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']
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']希望这有帮助!谢谢!
9条答案
按热度按时间qvtsj1bj1#
使用列表解析:
iqih9akk2#
你可以使用zip:
或者,Python 3中
zip
不生成列表:或者
或者,(我的最爱)使用numpy:
dw1jzc5e3#
遇到了同样的问题,并对每个解决方案的性能感到好奇。
下面是
%timeit
:第一个numpy-way,转换数组:
使用列表解析的完全原生(如@alecxe所解释的):
另一种使用
zip
的原生方式(如@dawg所解释的):第二种 numpy 方式。@dawg也解释道:
令人惊讶的是(好吧,至少对我来说)使用列表理解的原生方式是最快的,比numpy-way快了大约10倍。在没有最终
list
的情况下运行两个numpy-way可以节省大约1 µs,这仍然是10倍的差异。请注意,当我用对
len
的调用包围每个代码片段时,为了确保Generators运行到最后,计时保持不变。o4hqfura4#
Python包含一个名为itemgetter的函数,用于返回列表中特定索引处的项:
向itemgetter()函数传递要检索的项的索引。要检索第一个项,可以使用itemgetter(0)。重要的是要理解itemgetter(0)本身返回一个函数。如果你传递一个列表给那个函数,你会得到特定的项:
当你将它与map()结合使用时,这是很有用的,map()将一个函数作为它的第一个参数,一个列表(或任何其他可迭代对象)作为第二个参数。它返回在可迭代对象中的每个对象上调用函数的结果:
请注意,map()返回一个生成器,因此将结果传递给list()以获得实际的列表。总而言之,你的任务可以这样完成:
这是使用列表解析的另一种方法,选择哪种方法在很大程度上取决于上下文、可读性和偏好。
更多信息:https://docs.python.org/3/library/operator.html#operator.itemgetter
p5cysglq5#
你的代码几乎正确。唯一的问题是列表解析的用法。
如果您使用like:(x[0] for x in lst),它返回一个生成器对象。如果您使用like:[x[0] for x in lst],它返回一个列表。
当您将列表解析输出追加到列表时,列表解析的输出是列表的单个元素。
lst2 = 'a',1,'x'
lst2[0] = ['a',1,'x']
请让我知道如果我错了。
l5tcr1uw6#
输出:
['a', 1, 'x']
deikduxw7#
你说你有一个现有的名单。所以我同意你的说法。
现在,您正在将生成器对象追加到第二个列表中。
但你可能希望它是一个第一项的列表
现在,我们将第一个项目的列表附加到现有列表中。如果你想将项目themeselves,而不是它们的列表添加到现有的项目中,你可以使用list.extend。在这种情况下,我们不必担心添加生成器,因为extend将使用该生成器添加从那里获得的每个项,以扩展当前列表。
或
https://docs.python.org/3.4/tutorial/datastructures.html#more-on-listshttps://docs.python.org/3.4/tutorial/datastructures.html#list-comprehensions
qlckcl4x8#
您可以将列表列表中的第一个值提取到新列表中,如下所示:
5n0oy7gb9#
另一个我可以建议的答案是
输出如下
['a',1,'x']
希望这有帮助!谢谢!