0

Say I have a list of lists for example:

list0 = [[a, .5, .3], [b, .3, .8], [c, .7, 1.3], [d, 1.03, .2]]

I want to call the second element of each sublist for output to a list I assumed this would work.

input: print(list0[:][1])

output: [b, .3, .8]

but I was hoping to get this instead: (.5, .3, .7, 1.03)

Is there a possible way to call all sublists and access their elements without looping through whole list to create a new one? Can you compare times and describe why we can't call all or a range of sublists to get an element from each without looping through twice, once to get sublists and once to access each of them?

user102785
  • 11
  • 3
  • `list0[:]` just makes a (shallow) copy of the list. It is **not** an iterator. You have to use a loop (or list comprehension) to access the sublists. – hpaulj Dec 09 '20 at 21:02
  • Does this answer your question? [How to extract the n-th elements from a list of tuples?](https://stackoverflow.com/questions/3308102/how-to-extract-the-n-th-elements-from-a-list-of-tuples) – ShlomiF Dec 09 '20 at 21:04
  • How is list comprehension different from just looping through this shallow copy? It works but still feels inefficient if you already call each sublist why can't you call there element at the same time? – user102785 Dec 09 '20 at 21:06
  • 1
    `list0[:]` is just a variation on index with a slice, `list0[:2]`. I can't off hand point you to documentation since list handling is something I learned years ago from basic Python books. The idea of doing things "without loops" belongs to `numpy`, not python lists. – hpaulj Dec 09 '20 at 21:11
  • I realize this is a very basic question and I'm prepared to have to go deeper to how the data types arer stored. For quick answer would this method "without loops" work just with numpy list or array? – user102785 Dec 09 '20 at 21:16

2 Answers2

1

Just use a list comprehension -

second_element_of_each_sublist = [x[1] for x in list0]

or alternatively, use a map coupled with itemgetter -

from operator import itemgetter
second_element_of_each_sublist  = list(map(itemgetter(1), list0))

Avoiding loops altogether isn't gonna happen, at least if you take into account what might be going on behind the scenes. It's just a question of efficiency...

ShlomiF
  • 2,686
  • 1
  • 14
  • 19
  • This still loops through the sublists and creates a new one, why can't I call sublist elements while calling all or a range of sublists? – user102785 Dec 09 '20 at 21:08
1
In [196]: list0 = [['a', .5, .3], ['b', .3, .8], ['c', .7, 1.3], ['d', 1.03, .2]]

Some comparative times:

The recommended list comprehension:

In [197]: timeit [l[1] for l in list0]
410 ns ± 17.6 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

Starting with a list version of 'transpose':

In [198]: timeit list(zip(*list0))[1]
661 ns ± 3.63 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

Selecting a column from an array:

In [199]: timeit np.array(list0)[:,1]
16 µs ± 177 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

The reason numpy questions often ask "without loops", is that Python level iteration on numpy arrays is slow. Where possible we want to use the fast compiled numpy code (which still has loops). But when starting from a list, creating the array is relatively expensive.

Starting with an array, column indexing is fast:

In [200]: %%timeit A = np.array(list0)
     ...: A[:,1]
325 ns ± 11.6 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

Iteration on an array is slower than the same iteration on a list:

In [201]: %%timeit A = np.array(list0)
     ...: [a[1] for a in A] 
5.47 µs ± 96.7 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
hpaulj
  • 221,503
  • 14
  • 230
  • 353
  • Thank you for both showing the possibility with numpy and how inefficient it is. I suppose it has to do with the way lists don't have cols and rows when each sublist can be different lengths – user102785 Dec 09 '20 at 21:45
  • This answers the practical part but I'm still not sure why lists cannot call each element of there sublists like cols and rows? – user102785 Dec 09 '20 at 21:49
  • 1
    Lists are not multidimensional. A list contains references to other objects, which may themselves be lists. But the outer list does not have any methods for performing actions on its elements. Notions such as rows and columns are meaningless when dealing with lists. – hpaulj Dec 09 '20 at 21:54