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


  1. Python can refer to list elements by their index. It’ just ugly.