Python's iter
Coming from older languages like Fortran and Matlab, I was confused by the way Python refers to list elements (i.e. not by their index). Take a list comprehension for example
y= [f(j) for j in x]
Elegant, concise, and clear. How about a Fibonacci sequence, where the sum of an element is the sum of the previous two? How do you refer to the elements without the index1? I don’t know. But here is a more real example.
The Problem
I wanted to read financial statements, but my bank doesn’t write the year in the date of the transactions, only the month and day. This is a problem if the statement spans December and January.
For example, let’s say we have l=[10,11,12,12,12,1,1,1,1,2,2,3,4,5]
representing the months for these transactions, how to tell the program “if you see 12 followed by 1, consider what’s before 1 to be the current year, and neglect everything after. Or, consider what’s after 12 to be the current year, and neglect everything before”?
from pandas import Series
l=[10,11,12,12,12,1,1,1,1,2,2,3,4,5]
a=iter(l)
nextelem=next(a)
found=False
problem=False
status=[]
n=1
while n<len(l):
if found:
problem=True
thiselem, nextelem = nextelem, next(a)
if thiselem==12 and nextelem==1:
found=True
status.append(problem)
n=n+1
status.append(status[-1])
S=Series(status)
L=Series(l)
S
is a binary index for status. It marks the elements before the condition “this element is 12 and the next element is 1” as False
, and what’s after as True
. This makes their selection easy using pandas, like this: L[S]
.
keepgoing=True
while keepgoing:
reply=input('[D] delete December and before, [J] delete January and after, [N] do Nothing > ')
if reply=='D':
L=L[S]
keepgoing=False
elif reply=='J':
L=L[~S]
keepgoing=False
elif reply=='N':
keepgoing=False
else:
keepgoing=True
print(L)
An Alternative Method
The problem above can be solved probably more easily using enumerate
, but I have my reasons for using the above approach.
l=[10,11,12,12,12,1,1,1,1,2,2,3,4,5]
for idx, val in enumerate(l):
if val==1 and preval==12:
idx_1=idx
preval=val
print(l[:idx_1]) #[10, 11, 12, 12, 12]
print(l[idx_1:]) #[1, 1, 1, 1, 2, 2, 3, 4, 5]
Python’s Itertools
Below are some usage examples of Python’s itertools
-
Python can refer to list elements by their index. It’ just ugly. ↩