In Python list comprehension is it possible to access the item index?
Asked Answered
G

4

151

Consider the following Python code with which I add in a new list2 all the items with indices from 1 to 3 of list1:

for ind, obj in enumerate(list1):
    if 4 > ind > 0:
        list2.append(obj)

How would you write this using list comprehension, if I have no access to the indices through enumerate?

something like:

list2 = [x for x in list1 if 4 > ind > 0]

but since I have no ind number, would this work?

list2 = [x for x in enumerate(list1) if 4 > ind > 0]
Gav answered 13/2, 2013 at 22:59 Comment(3)
I guess your actual use case is more complex, but you could simply be slicing list1[1:4] hereCeiling
you mean like I could slice the list inside the list comprehension? like : [x for x in list1[1:4]] ?Gav
@PavAmetvic, no @Ceiling means you can just write list2 = list1[1:4]Pantechnicon
S
272
list2 = [x for ind, x in enumerate(list1) if 4 > ind > 0]
Skees answered 13/2, 2013 at 23:1 Comment(0)
K
49

If you use enumerate, you do have access to the index:

list2 = [x for ind, x in enumerate(list1) if 4>ind>0]
Kokanee answered 13/2, 2013 at 23:2 Comment(0)
P
14

Unless your real use case is more complicated, you should just use a list slice as suggested by @wim

>>> list1 = ['zero', 'one', 'two', 'three', 'four', 'five', 'six']
>>> [x for ind, x in enumerate(list1) if 4 > ind > 0]
['one', 'two', 'three']
>>> list1[1:4]
['one', 'two', 'three']

For more complicated cases - if you don't actually need the index - it's clearer to iterate over a slice or an islice

list2 = [x*2 for x in list1[1:4]]

or

from itertools import islice
list2 = [x*2 for x in islice(list1, 1, 4)]

For small slices, the simple list1[1:4]. If the slices can get quite large it may be better to use an islice to avoid copying the memory

Pantechnicon answered 14/2, 2013 at 0:1 Comment(2)
thanks but since I want to perform an operation on 'x' inside the comprehension (lets say x*x) before I store it inside the new list, it looks like using the slice inside the list comprehension is the best way ! thanksGav
@PavAmetvic, ok those cases are still simple enough to not need enumerationPantechnicon
S
8

For those wondering, you can just as easily store the matching indices as the result of the list comprehension if your use-case requires it. It may be that you need to evaluate the value of each item in the list to determine if it matches some value or pattern, and that you just want to obtain a list of the matching indices for later processing rather than the matching values.

This can be done as shown below:

>>> values = ['zero', 'one', 'two', 'three', 'four', 'five', 'six']
>>> search = ['one', 'three', 'five']
>>> matches = [i for i, x in enumerate(values) if x in search]
>>> print(matches)
[1, 3, 5]

The important part above is the use of the [i for i, x in enumerate(l) if ...] pattern in the list comprehension, where the index i is being captured rather than the value x which would be achieved using the more typical [x for x in l if ...] or the alternate [x for i, x in enumerate(l) if ...] enumeration list comprehension patterns.

Sewan answered 15/6, 2021 at 18:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.