问题:提取每个子列表的第一项
我想知道什么是提取列表列表中每个子列表的第一项并将其附加到新列表的最佳方法。所以,如果我有:
lst = [[a,b,c], [1,2,3], [x,y,z]]
我想退出a
,1
并x
从中创建一个单独的列表。
我试过了:
lst2.append(x[0] for x in lst)
I am wondering what is the best way to extract the first item of each sublist in a list of lists and append it to a new list. So if I have:
lst = [[a,b,c], [1,2,3], [x,y,z]]
and I want to pull out a
, 1
and x
and create a separate list from those.
I tried:
lst2.append(x[0] for x in lst)
回答 0
使用列表理解:
>>> lst = [['a','b','c'], [1,2,3], ['x','y','z']]
>>> lst2 = [item[0] for item in lst]
>>> lst2
['a', 1, 'x']
Using list comprehension:
>>> lst = [['a','b','c'], [1,2,3], ['x','y','z']]
>>> lst2 = [item[0] for item in lst]
>>> lst2
['a', 1, 'x']
回答 1
您可以使用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])
You could use zip:
>>> lst=[[1,2,3],[11,12,13],[21,22,23]]
>>> zip(*lst)[0]
(1, 11, 21)
Or, Python 3 where zip
does not produce a list:
>>> list(zip(*lst))[0]
(1, 11, 21)
Or,
>>> next(zip(*lst))
(1, 11, 21)
Or, (my favorite) use 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])
回答 2
有同样的问题,并对每个解决方案的性能感到好奇。
这是 %timeit
:
import numpy as np
lst = [['a','b','c'], [1,2,3], ['x','y','z']]
第一种numpy方式,转换数组:
%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方式快约10倍。在没有最终运算的情况下运行两个numpy-way list
可以节省大约1 µs,仍然相差10倍。
请注意,当我用调用包围每个代码段len
以确保Generators一直运行到最后时,时间保持不变。
Had the same issue and got curious about the performance of each solution.
Here’s is the %timeit
:
import numpy as np
lst = [['a','b','c'], [1,2,3], ['x','y','z']]
The first numpy-way, transforming the array:
%timeit list(np.array(lst).T[0])
4.9 µs ± 163 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
Fully native using list comprehension (as explained by @alecxe):
%timeit [item[0] for item in lst]
379 ns ± 23.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Another native way using zip
(as explained by @dawg):
%timeit list(zip(*lst))[0]
585 ns ± 7.26 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Second numpy-way. Also explained by @dawg:
%timeit list(np.array(lst)[:,0])
4.95 µs ± 179 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
Surprisingly (well, at least for me) the native way using list comprehension is the fastest and about 10x faster than the numpy-way. Running the two numpy-ways without the final list
saves about one µs which is still in the 10x difference.
Note that, when I surrounded each code snippet with a call to len
, to ensure that Generators run till the end, the timing stayed the same.
回答 3
Python包含一个名为itemgetter的函数,用于在列表中的特定索引处返回项目:
from operator import itemgetter
向itemgetter()函数传递要检索的项目的索引。要检索第一个项目,可以使用itemgetter(0)。要了解的重要一点是itemgetter(0)本身会返回一个函数。如果将列表传递给该函数,则会得到特定的项目:
itemgetter(0)([10, 20, 30]) # Returns 10
当将其与map()结合使用时,此功能很有用,后者将一个函数作为其第一个参数,并将列表(或任何其他可迭代)作为第二个参数。它返回在iterable中的每个对象上调用该函数的结果:
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
Python includes a function called itemgetter to return the item at a specific index in a list:
from operator import itemgetter
Pass the itemgetter() function the index of the item you want to retrieve. To retrieve the first item, you would use itemgetter(0). The important thing to understand is that itemgetter(0) itself returns a function. If you pass a list to that function, you get the specific item:
itemgetter(0)([10, 20, 30]) # Returns 10
This is useful when you combine it with map(), which takes a function as its first argument, and a list (or any other iterable) as the second argument. It returns the result of calling the function on each object in the iterable:
my_list = [['a', 'b', 'c'], [1, 2, 3], ['x', 'y', 'z']]
list(map(itemgetter(0), my_list)) # Returns ['a', 1, 'x']
Note that map() returns a generator, so the result is passed to list() to get an actual list. In summary, your task could be done like this:
lst2.append(list(map(itemgetter(0), lst)))
This is an alternative method to using a list comprehension, and which method to choose highly depends on context, readability, and preference.
More info: https://docs.python.org/3/library/operator.html#operator.itemgetter
回答 4
您的代码几乎是正确的。唯一的问题是列表理解的用法。
如果使用like :(对于x在第一个中为x [0]),它将返回一个生成器对象。如果您使用类似:[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’]
如果我不正确,请告诉我。
Your code is almost correct. The only issue is the usage of list comprehension.
If you use like: (x[0] for x in lst), it returns a generator object. If you use like: [x[0] for x in lst], it return a list.
When you append the list comprehension output to a list, the output of list comprehension is the single element of the list.
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’]
Please let me know if I am incorrect.
回答 5
lst = [['a','b','c'], [1,2,3], ['x','y','z']]
outputlist = []
for values in lst:
outputlist.append(values[0])
print(outputlist)
输出: ['a', 1, 'x']
lst = [['a','b','c'], [1,2,3], ['x','y','z']]
outputlist = []
for values in lst:
outputlist.append(values[0])
print(outputlist)
Output: ['a', 1, 'x']
回答 6
您说您有一个现有列表。所以我会去。
>>> 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']]
现在,我们将第一项列表添加到现有列表中。如果要将项目主题本身(而不是它们的列表)添加到现有主题中,则可以使用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-lists https://docs.python.org/3.4/tutorial/datastructures.html#list-comprehensions
You said that you have an existing list. So I’ll go with that.
>>> lst1 = [['a','b','c'], [1,2,3], ['x','y','z']]
>>> lst2 = [1, 2, 3]
Right now you are appending the generator object to your second list.
>>> lst2.append(item[0] for item in lst)
>>> lst2
[1, 2, 3, <generator object <genexpr> at 0xb74b3554>]
But you probably want it to be a list of first items
>>> lst2.append([item[0] for item in lst])
>>> lst2
[1, 2, 3, ['a', 1, 'x']]
Now we appended the list of first items to the existing list. If you’d like to add the items themeselves, not a list of them, to the existing ones, you’d use list.extend. In that case we don’t have to worry about adding a generator, because extend will use that generator to add each item it gets from there, to extend the current list.
>>> lst2.extend(item[0] for item in lst)
>>> lst2
[1, 2, 3, 'a', 1, 'x']
or
>>> 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-lists https://docs.python.org/3.4/tutorial/datastructures.html#list-comprehensions
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。