Firstly, your "messy way" is ok, there's nothing wrong with using indices into the dataframe, and this will not be too slow. iterrows() itself isn't terribly fast.
A version of your first idea that would work would be:
row_iterator = df.iterrows()
_, last = row_iterator.next() # take first item from row_iterator
for i, row in row_iterator:
print(row['value'])
print(last['value'])
last = row
The second method could do something similar, to save one index into the dataframe:
last = df.irow(0)
for i in range(1, df.shape[0]):
print(last)
print(df.irow(i))
last = df.irow(i)
When speed is critical you can always try both and time the code.