1

So I was wondering if there is a way to print the nth value (not the last value) from a For Loop output. For eg: let's suppose I want to print just the 'fifth-to-last' value or just the 'third-to-last' value from the For Loop output. Any idea how can I do that? I am newbie at coding/python and I am building up this code after doing a lot of research & learning on the way. So any help appreciated.

Currently, the code below is giving me the last value.

from datetime import timedelta, date

def daterange(start_date, end_date):
    for n in range(int(start_date.day), int((end_date - start_date).days), 90):
        yield start_date + timedelta(n)

start_date = date(2016, 1, 1)
end_date = date.today()
for single_date in daterange(start_date, end_date):
    x = single_date.strftime("%Y-%m-%d")

print(x)
2
  • A problem with this code is it assumes (implicitly) that the iterator is non-empty. If the iterator happens to be empty it'll raise UnboundLocalError. Commented Mar 9, 2020 at 6:56
  • Well, I got the code from this link here. stackoverflow.com/questions/1060279/… I wasn't aware of this issue. How can I fix this? Commented Mar 9, 2020 at 7:17

3 Answers 3

3

The technique is to accumulate the results in a container, and then print the n-th element back.

One possibility is to use collections.deque() with a maxlen value set to n.

from datetime import timedelta, date
from collections import deque

def daterange(start_date, end_date):
    for n in range(int(start_date.day), int((end_date - start_date).days), 90):
        yield start_date + timedelta(n)

window = deque([], maxlen=5)
start_date = date(2016, 1, 1)
end_date = date.today()
for single_date in daterange(start_date, end_date):
    x = single_date.strftime("%Y-%m-%d")
    window.append(x)

print(window[0])

The above code outputs the fifth oldest entry.

2018-12-17

The above code accumulates the most recent values in a sliding window of width 5. The oldest value in at position 0 and the newest value is at position -1.

You can change the 5 to be any value of n that you need.

Hope this helps :-)

Sign up to request clarification or add additional context in comments.

3 Comments

Yes, this helps a lot. :) I would never have been able to guess this. Also, I learned about something new as well. Thank you so much.
This might be quite memory-consiming if you're looking for nth element for large n. I think Raghul Raj's solution is better for general case.
The OP listed examples of 3rd to last or 5th to last. There was no mention of hundreds of thousands or millions that would consume much memory.
1

You can use enumerate while looping which gives the iteration count. You can provide a condition inside based on the values you need to print as follows:

from datetime import timedelta, date

def daterange(start_date, end_date):
    for n in range(int(start_date.day), int((end_date - start_date).days), 90):
        yield start_date + timedelta(n)

start_date = date(2016, 1, 1)
end_date = date.today()
n=5
length =len(list(daterange(start_date, end_date)))

for i,single_date in enumerate(daterange(start_date, end_date)):
    x = single_date.strftime("%Y-%m-%d")
    if i == length-n:
        print(x)

Hope that helps

4 Comments

Thank you for your answer. I was looking for just one specific value from the list and Raymond Hettinger solution gives me what I was looking for. Appreciate the help anyways. :)
Sorry I didn't get the question the previous time. I've updated my answer now. Let me know if this is what you expect.
if I have to automatically update the n value based on a condition how can I do that?
In that case, you can write it under a function and pass n as a parameter to it
0

You can use slicing to only get certain elements by index. Slicing does not work on generators however, so you will need to cast to a list.

from datetime import timedelta, date

def daterange(start_date, end_date):
    for n in range(int(start_date.day), int((end_date - start_date).days), 90):
       yield start_date + timedelta(n)

start_date = date(2016, 1, 1)
end_date = date.today()
for single_date in list(daterange(start_date, end_date))[4:]:
    x = single_date.strftime("%Y-%m-%d")
    print(x)

This will print the 5th (index: 4) to last element.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.