3

I know that maps, range, filters etc. in python3 return iterables, and only calculate value when required. Suppose that there is a map M. I want to print the i^th element of M.

One way would be to iterate till i^th value, and print it:

for _ in range(i):
    next(M)
print(next(M))

The above takes O(i) time, where I have to find the i^th value.

Another way is to convert to a list, and print the i^th value:

print(list(M)[i])

This however, takes O(n) time and O(n) space (where n is the size of the list from which the map M is created). However, this suits the so-called "Pythonic way of writing one-liners."

I was wondering if there is a syntactic sugar to minimise writing in the first way? (i.e., if there is a way which takes O(i) time, no extra space, and is more suited to the "Pythonic way of writing".)

2
  • Are you specifically talking about map? because range objects are indexable in O(1) time. range(1, 100)[-1] returns 99
    – DeepSpace
    Commented Jul 26, 2020 at 14:49
  • maps and filters basically, although I didn't know about range objects being indexable in O(1) time.
    – ghost
    Commented Jul 26, 2020 at 14:52

2 Answers 2

2

You can use islice:

from itertools import islice

i = 3
print(next(islice(iterable), i, i + 1))

This outputs '3'.

It actually doesn't matter what you use as the stop argument, as long as you call next once.

1

Thanks to @DeepSpace for the reference to the official docs, I found the following:

from more_itertools import nth

print(nth(M, i))

It prints the element at i^th index of the iterable.

Not the answer you're looking for? Browse other questions tagged or ask your own question.