Swap the square brackets for parentheses in the return statement and it will return a generator expression.
That will read the file as needed (ie as you iterate over it) instead of loading the entire thing in memory.
for record in read_portfolio(fn):
# do stuff