Using iterators to write in the structure being iterated through?

Pierre Thibault thibault at physics.cornell.edu
Thu Jul 27 10:02:40 EDT 2006


On Wed, 26 Jul 2006 20:59:12 +0200, Peter Otten wrote:

> Pierre Thibault wrote:
> 
>> Hum, this example seems like a special case not really appropriate for my
>> needs. Let me make my problem a little more precise. The objects I'll want
>> to iterate through will always contain some floats. Very often, I guess
>> they will be numpy.ndarray instances, but they can be something else as
>> well. For instance, I will have to deal with arrays having internal
>> symmetries (crystallographic datasets). The most efficient thing to do
>> with those is save only the unique values and keep track of the symmetry
>> operations needed to extract other values.
>> 
>> A 1d examples: I have a class which represents a unit cell
>> which has the additional mirror symmetry in the middle of the cell. Say
>> C is an instance of this class representing data on a 50-long array. Only
>> 25 datum will be stored in C, and the class takes care of giving the value
>> of C[0] if C[49] is asked, C[1] for C[48], and so on. Since crystals are
>> periodic, the translational symmetry can also be managed (C[-1] == C[49]
>> == C[0], C[-2] == C[48] == C[1]...). In any case, the user of this object
>> need not know how the data is stored: for him, C is just a funny
>> array-like object defined from -infinity to +infinity on a 1-D lattice.
>> 
>> Now, I want to do simple math operations on the data in C. Doing a loop
>> from 0 to 49 would loop twice through the actual data. In this
>> context, an iterator is perfect since it can take care internally of going
>> through the data only once, so it would be great to access _AND MODIFY_
>> data over which I iterate.
> 
> That would not only be nice but crucial to the integrity of your data. You'd
> have to explicitly forbid operations on individual cells as applying an
> operation to a single cell would change two or more cells, depending of the
> kind of symmetry.
> 
>> I now realize I don't know how to do that with numpy.ndarray either. It
>> looks like the only way I can modify the content of an array is by using
>> the [] notation (that is, in random access). For instance, the
>> following will not change the state of a:
>> 
>> import numpy
>> a = numpy.array([[1.,2.,3.],[4.,5.,6.],[7.,8.,9.]])
>> 
>> for c in a.flat
>>     c += 2.
>> 
>> Of course, I know that a += .2 would be alright, but this is not general
>> enough for more complicated classes.
>> 
>> So I guess my problem is worst than I thought.
> 
> Indeed, but I don't think it would be easier in C++...
> 
> Peter

Well, no, C++ is better in this case because the thing you iterate over is
a generalized pointer, which can be dereferenced to get access to the
memory. So in other word, iterator.next() (in python) is a copy, while
*iterator (in C++) is a reference. 

Thanks anyway for your comments!

Pierre




More information about the Python-list mailing list