I have a list of strings. I want to iterate through them and print only the first three items. However, if one of the items is equivalent to "deleted", then I want to skip that item and print the next item (so long as it doesn't equal to "deleted" as well).
In other words, I want to filter out a string I don't want and print the first three items in a list. Here is my code:
days = ["deleted", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
position = 3
for res_counter, day in enumerate(days[:position], start=1):
if "deleted" in day:
position += 1
continue
else:
print(res_counter, day)
The output I expect:
1 Sun
2 Mon
3 Tue
The output I receive:
2 Sun
3 Mon
No errors are thrown, I am just not getting the output I would like. I know my logic must be flawed, if anyone could help I would greatly appreciate it.
The problem is you have already sliced the list at the first value of position
here:
days[:position]
This means incrementing position
later will not add elements to this slice. With some adjustments, your solution will work:
idx = 1
for day in days:
if "deleted" in day:
continue
else:
print(idx, day)
idx += 1
if idx > position:
break
This outputs:
1 Sun
2 Mon
3 Tue
Notice we will potentially iterate through all of days
because we can't know in advance how many elements in it will contain "deleted"
.
A much shorter (but still equally efficient) process would be to use filter
and itertools.islice
:
from itertools import islice
position = 3
for idx, day in islice(enumerate(filter(lambda x : "deleted" not in x, days), 1), position):
print(idx, day)
What we're doing here: this line
enumerate(filter(lambda x : "deleted" not in x, days), 1)
returns the numbered pairs idx, day
while filtering out elements with "deleted"
in them. Specifically, this is a generator expression, so we do not need to process all of days
in advance. Next
islice(iterable, position)
says return the first position
elements of the iterable (in this case, it is our generator expression). The result is that we do not process more elements than we need to, but we are able to achieve the same result in fewer lines.