0

Hello recently I am trying to figure out list comprehension. And it looks like I suck at this :/

Here is my code I am trying to remake using list comprehension

base = datetime.datetime.today()
date_list = [base - datetime.timedelta(days=x) for x in range(61)]
del date_list[0]
date_list.reverse()

weekend = []
dates = []
for idx, val in enumerate(date_list):
    dates.append(str(val)[0:10])
    dates.append(str(val)[0:10])
    case = val.isoweekday()
    if case == 6 or case == 7:
        weekend.append(str(val)[0:10])

I looked it out how to use enumerate using this method and i found this:

[val for idx, val in enumerate(date_list)]

But i don't know how to continue this idea.

I would really appreciate some help :)

6
  • Is doing dates.append(str(val)[0:10]) twice intentional? Commented Aug 13, 2021 at 8:02
  • Yes, I need it to be this way Commented Aug 13, 2021 at 8:05
  • 1
    Why the use of enumerate? doesn't look like you need the index idx. Commented Aug 13, 2021 at 8:05
  • Well.. you are right. This is a leftover from previous version. I didn't really think about this. Thanks Commented Aug 13, 2021 at 8:06
  • 1
    Notwithstanding the fact that you don't need to use enumerate, why use a list comprehension when your loop does what you need? Sure, it can be done using list comprehension but it'll end up being unreadable/unmaintainable Commented Aug 13, 2021 at 8:08

2 Answers 2

2

This

dates = []
for idx, val in enumerate(date_list):
    dates.append(str(val)[0:10])
    dates.append(str(val)[0:10])

can be reworked into list comprehension but beware that you might end with low readibility. Consider similar but simpler case:

digits = [1,2,3,4,5,6,7,8,9]
numbers = []
for val in digits:
    numbers.append(val)
    numbers.append(val)
print(numbers)

output

[1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9]

First step is to rework code such that is there is exactly one .append, in this case replace for loop with

for val in digits:
    for _ in range(2):
        numbers.append(val)

As you might check output is same, final step is to rewrite that into list comprehension which in case of nested for is shallow-deep to left-right thus outcome is

digits = [1,2,3,4,5,6,7,8,9]
numbers = [val for val in digits for _ in range(2)]
print(numbers)

This approach might be also used if you have more levels of nesting.

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

Comments

1

For list comprehension with if condition it should look like this [function(x) if condition(x) else other_function(x) for x in list] So for your case, I would say:

base = datetime.datetime.today()
date_list = [base - datetime.timedelta(days=x) for x in range(1,61)]
date_list.reverse()

weekend = [date.strftime("%m/%d/%Y, %H:%M:%S")  for date in date_list if (date.weekday()==5 or date.weekday()==6)]
dates=[]
for date in date_list:
    dates.extend([date.strftime("%m/%d/%Y, %H:%M:%S"),date.strftime("%m/%d/%Y, %H:%M:%S")])


It's better to use strftime to transform datetime in the format you want: https://docs.python.org/fr/3.6/library/datetime.html#strftime-and-strptime-behavior

4 Comments

I copied ur code but it says there is a syntax error somwhere near for in date.weekday()==7) for date in date_list
The list comprehension is incorrect. This should be the right one: weekend = [date.strftime("%m/%d/%Y, %H:%M:%S") for date in date_list if (date.weekday()==6 or date.weekday()==7) ] The order of the for and if statement matters.
Indeed, my bad, to use this you absolutly need a else statement which is not really suitable in your case
I also belive that .weekday() returns different values than .isoweekday(). Instead of (date.weekday()==6 or date.weekday()==7) 6 and 7 should be changed like so (date.weekday()==5 or date.weekday()==6)

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.