accessing elements in multi-dimensional sequences

  • Thread starter Rodrigo Daunaravicius
  • Start date
R

Rodrigo Daunaravicius

Is there an elegant way to directly refer the 2nd dimension of a
multi-dimensional sequence (like the nth character in a list of strings).
An example would be deleting the newline in all the strings from a list
obtained through readlines without recurring to 'for' loops.
I would expect this to work:
['0891931243\n', '0325443777\n', '0933477028\n', '0699624617\n',
'0922210996\n']
['0891931243', '0325443777', '0933477028', '0699624617', '0922210996']

But it doesn't, d remains unchanged.

Another attempt produced what seemed to me like a counter-intuitive result
['0891931243\n', '0325443777\n', '0933477028\n', '0699624617\n']


Regards from a python newbie,
Rodrigo Daunarovicius
 
M

Matteo Dell'Amico

Rodrigo said:
Is there an elegant way to directly refer the 2nd dimension of a
multi-dimensional sequence (like the nth character in a list of strings).
An example would be deleting the newline in all the strings from a list
obtained through readlines without recurring to 'for' loops.
I would expect this to work:


['0891931243\n', '0325443777\n', '0933477028\n', '0699624617\n',
'0922210996\n']

['0891931243', '0325443777', '0933477028', '0699624617', '0922210996']

But it doesn't, d remains unchanged.

Another attempt produced what seemed to me like a counter-intuitive result


['0891931243\n', '0325443777\n', '0933477028\n', '0699624617\n']


Regards from a python newbie,
Rodrigo Daunarovicius

You can express that as [s[:-1] for s in d].
Besides, strings are immutable: if s is a string, you can't do something
like s[3] = 'a': though, you can create a new object and tell s to refer
to it: s = s[:3] + 'a' + s[4:]

If all you want to do is remove trailing whitespace, have also a look at
the string strip, lstrip and rstrip methods.
 
P

Peter Otten

Rodrigo said:
Is there an elegant way to directly refer the 2nd dimension of a
multi-dimensional sequence (like the nth character in a list of strings).

[list of strings example]

While your example doesn't work, as Matteo already explained, the Numeric
package provides an intuitive way to refer to the nth dimension of a
matrix:
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
array([[0, 1],
[3, 4],
[6, 7]])

In spite of its name, Numeric is not limited to numbers:
d = ['0891931243\n', '0325443777\n', '0933477028\n', '0699624617\n']
a = Numeric.array(d)
a.tostring() '0891931243\n0325443777\n0933477028\n0699624617\n'
a[:, :-1].tostring()
'0891931243032544377709334770280699624617'

Note that shorter strings are filled with spaces:
Numeric.array(["123\n", "4\n", "789\n"]).tostring()
'123\n4\n 789\n'

Of course this is overkill for your example use case.

Peter
 
A

Anton Vredegoor

Rodrigo Daunaravicius said:
Is there an elegant way to directly refer the 2nd dimension of a
multi-dimensional sequence (like the nth character in a list of strings).
An example would be deleting the newline in all the strings from a list
obtained through readlines without recurring to 'for' loops.

d = ['0891931243\n', '0325443777\n', '0933477028\n',
'0699624617\n', '0922210996\n']

#swap rows and columns, with the side effect of turning
#strings into lists, strings must be of equal length or
#else some information will be lost:

d1 = zip(*d)

#remove a row (corresponds to a *column* in the old view)
#this is an elementary operation now:

del d1[-1]

#swapping again restores the old row and column view:

d1 = zip(*d1)

#join the elements of the sublists in order to produce strings:

d1 = map(''.join,d1)

print d1

#output is:
#['0891931243', '0325443777', '0933477028', '0699624617',
#'0922210996']


While this way of coding enables one to *think* about the problem more
efficiently it is not necessarily the most efficient algorithm for
accomplishing this specific effect. If it's fast enough however, why
not reduce ones mental computing cycles and let the computer do all
the leg work?

It might even ameliorate entropy problems later on in the evolution of
the universe since the operations could probably be reversed more
efficiently even if the computer moves more electrons through the
silicon?

Anton
 
D

Duncan Booth

(e-mail address removed) (Anton Vredegoor) wrote in
d = ['0891931243\n', '0325443777\n', '0933477028\n',
'0699624617\n', '0922210996\n']

#swap rows and columns, with the side effect of turning
#strings into lists, strings must be of equal length or
#else some information will be lost:

d1 = zip(*d)

#remove a row (corresponds to a *column* in the old view)
#this is an elementary operation now:

del d1[-1]

#swapping again restores the old row and column view:

d1 = zip(*d1)

#join the elements of the sublists in order to produce strings:

d1 = map(''.join,d1)

print d1

#output is:
#['0891931243', '0325443777', '0933477028', '0699624617',
#'0922210996']

This, of course, only works when the strings are all exactly the same
length. If they are different lengths it truncates all the strings to the
length of the shortest.
 
R

Rodrigo Daunaravicius

Thank you all for you great tips! Matteo's list comprehension solution
suits best my particular problem and I'll be using it.

You can express that as [s[:-1] for s in d].


It was great to know about the Numeric package, Peter, it will be really
useful for some of the matrix handling I'm going to need.
Anton's solution was a good brain teaser. I couldn't find in the docs what
is the meaning of the asterisk in zip(*d), though. Nothing to do with C
pointers, I guess?


Rodrigo Daunaravicius said:
Is there an elegant way to directly refer the 2nd dimension of a
multi-dimensional sequence (like the nth character in a list of strings).
An example would be deleting the newline in all the strings from a list
obtained through readlines without recurring to 'for' loops.

d = ['0891931243\n', '0325443777\n', '0933477028\n',
'0699624617\n', '0922210996\n']

#swap rows and columns, with the side effect of turning
#strings into lists, strings must be of equal length or
#else some information will be lost:

d1 = zip(*d)

Thanks again,
Rodrigo Daunaravicius
 
D

Duncan Booth

I couldn't find in the docs what
is the meaning of the asterisk in zip(*d), though. Nothing to do with C
pointers, I guess?

Python Reference Manual, section 5.3.4 Calls:

If the syntax "*expression" appears in the function call, "expression" must
evaluate to a sequence. Elements from this sequence are treated as if they
were additional positional arguments; if there are postional arguments
x1,...,xN , and "expression" evaluates to a sequence y1,...,yM, this is
equivalent to a call with M+N positional arguments x1,...,xN,y1,...,yM.
 
R

Rodrigo Daunaravicius

Python Reference Manual, section 5.3.4 Calls:

If the syntax "*expression" appears in the function call, "expression" must
evaluate to a sequence. Elements from this sequence are treated as if they
were additional positional arguments; if there are postional arguments
x1,...,xN , and "expression" evaluates to a sequence y1,...,yM, this is
equivalent to a call with M+N positional arguments x1,...,xN,y1,...,yM.

Got it. I was looking in the wrong places. '*' is not the easiest string to
conduct a search on, if it's not referred to as an 'asterisk' somewhere on
the text.

Thanks, Duncan!
Rodrigo Daunaravicius
 

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,755
Messages
2,569,536
Members
45,008
Latest member
HaroldDark

Latest Threads

Top