Extract first item of each sublist

Question:

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)
Asked By: konrad

||

Answers:

Using list comprehension:

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

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.

Answered By: Abhishek Mittal

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

Answered By: Hendrik

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])
Answered By: dawg

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

Answered By: Christian Abbott
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']

Answered By: PrabhuPrakash

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.

Answered By: jboi

The other answer I could suggest is

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

The output comes as follows

[‘a’, 1, ‘x’]

Hope this helps! Thanks!

Answered By: Sundar Gurunathan
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.