Confused with csv.reader copies

R

Robert Dailey

First, take a look at my example code:
-----------------------------------------------------
import csv

def pass1( reader ):
print reader.next()
print reader.next()

def pass2( reader ):
print reader.next()
print reader.next()

reader = csv.reader( open( "C:/IT/Method/SpaceImpact/code/tools/
ProfileViewer/performance_profile.csv", "rb" ) )

pass1( reader )
pass2( reader )
-----------------------------------------------------

The output is as follows:
-----------------------------------------------------
['0', 'root', '00:01:32.793591', '1']
['1', 'Engine::Tick', '00:00:25.886411', '1851']
['2', 'Sprite::Tick', '00:00:00.001495', '385']
['2', 'Entity::Tick', '00:00:00.001485', '45']
-----------------------------------------------------

I expected the output to be this:
-----------------------------------------------------
['0', 'root', '00:01:32.793591', '1']
['1', 'Engine::Tick', '00:00:25.886411', '1851']
['0', 'root', '00:01:32.793591', '1']
['1', 'Engine::Tick', '00:00:25.886411', '1851']
-----------------------------------------------------

My understanding is that objects are passed by reference, meaning
there is no hard copy of the data, however the copies passed to
functions do not affect the version passed in. In other words, when I
call "next" on the reference passed into each function, it should not
affect the variable that was originally passed in.

I'm attempting to use recursion to build a TreeCtrl in wxPython using
this data, and I can't get it to work properly if the variable outside
of the function call ends up having its state (e.g., its "next"
pointer) modified by passing it into other functions.

Any tips on getting this to work? I'm a native C++ programmer still
learning Python, so I apologize for any confusion. Thanks.
 
L

Larry Bates

Robert said:
First, take a look at my example code:
-----------------------------------------------------
import csv

def pass1( reader ):
print reader.next()
print reader.next()

def pass2( reader ):
print reader.next()
print reader.next()

reader = csv.reader( open( "C:/IT/Method/SpaceImpact/code/tools/
ProfileViewer/performance_profile.csv", "rb" ) )

pass1( reader )
pass2( reader )
-----------------------------------------------------

The output is as follows:
-----------------------------------------------------
['0', 'root', '00:01:32.793591', '1']
['1', 'Engine::Tick', '00:00:25.886411', '1851']
['2', 'Sprite::Tick', '00:00:00.001495', '385']
['2', 'Entity::Tick', '00:00:00.001485', '45']
-----------------------------------------------------

I expected the output to be this:
-----------------------------------------------------
['0', 'root', '00:01:32.793591', '1']
['1', 'Engine::Tick', '00:00:25.886411', '1851']
['0', 'root', '00:01:32.793591', '1']
['1', 'Engine::Tick', '00:00:25.886411', '1851']
-----------------------------------------------------

My understanding is that objects are passed by reference, meaning
there is no hard copy of the data, however the copies passed to
functions do not affect the version passed in. In other words, when I
call "next" on the reference passed into each function, it should not
affect the variable that was originally passed in.

I'm attempting to use recursion to build a TreeCtrl in wxPython using
this data, and I can't get it to work properly if the variable outside
of the function call ends up having its state (e.g., its "next"
pointer) modified by passing it into other functions.

Any tips on getting this to work? I'm a native C++ programmer still
learning Python, so I apologize for any confusion. Thanks.

By reference means that mutable objects can be modified (in place) by the
functions that they are passed into. This is a common mistake people make when
they first get started. Normally lists seem to throw people first.
I don't know how long the file is, but you probably should just read the entire
file into memory and process it from there.

-Larry
 
G

Gabriel Genellina

import csv

def pass1( reader ):
print reader.next()
print reader.next()

def pass2( reader ):
print reader.next()
print reader.next()

reader = csv.reader( open( "C:/IT/Method/SpaceImpact/code/tools/
ProfileViewer/performance_profile.csv", "rb" ) )

pass1( reader )
pass2( reader )

[expecting the two calls to print the same two lines]
My understanding is that objects are passed by reference, meaning
there is no hard copy of the data, however the copies passed to
functions do not affect the version passed in. In other words, when I
call "next" on the reference passed into each function, it should not
affect the variable that was originally passed in.

Both functions receive the *same* reader object, not a copy. Calling
next() affects the reader internal state, it doesn't matter where you call
it from.
You should read this threads from last week:
http://groups.google.com/group/comp.lang.python/browse_thread/thread/45732106f147ac07/
http://groups.google.com/group/comp.lang.python/browse_thread/thread/56e7d62bf66a435c/
I'm attempting to use recursion to build a TreeCtrl in wxPython using
this data, and I can't get it to work properly if the variable outside
of the function call ends up having its state (e.g., its "next"
pointer) modified by passing it into other functions.

Any tips on getting this to work? I'm a native C++ programmer still
learning Python, so I apologize for any confusion. Thanks.

The simplest way -if the file is not so huge- is to read the whole file
and keep the results in a list: lines = list(reader)
There are other alternatives using the itertools module but aren't easy to
grasp for a beginner.
 
J

Jeethu Rao

Robert said:
First, take a look at my example code:
-----------------------------------------------------
import csv

def pass1( reader ):
print reader.next()
print reader.next()

def pass2( reader ):
print reader.next()
print reader.next()

reader = csv.reader( open( "C:/IT/Method/SpaceImpact/code/tools/
ProfileViewer/performance_profile.csv", "rb" ) )

pass1( reader )
pass2( reader )
Like Gabriel suggested, using itertools.tee should do the trick.

-----------------------------------------------------

import csv
from itertools import tee

def pass1( reader ):
print reader.next()
print reader.next()

def pass2( reader ):
print reader.next()
print reader.next()

reader1,reader2 = tee( csv.reader( open( "C:/IT/Method/SpaceImpact/code/tools/
ProfileViewer/performance_profile.csv", "rb" ) ) )

pass1( reader1 )
pass2( reader2 )
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top