list comprehension

G

Guy Robinson

Hello,

Trying to change a string(x,y values) such as :

s = "114320,69808 114272,69920 113568,71600 113328,72272"

into (x,-y):

out = "114320,-69808 114272,-69920 113568,-71600 113328,-72272"

I tried this:

print [(a[0],-a[1] for a in x.split(',')) for x in e]

But it doesn't work. Can anyone suggest why or suggest an alternative
way? The text strings are significantly bigger than this so performance
is important.

TIA,

Guy
 
A

Andrew Bennetts

Hello,

Trying to change a string(x,y values) such as :

s = "114320,69808 114272,69920 113568,71600 113328,72272"

into (x,-y):

out = "114320,-69808 114272,-69920 113568,-71600 113328,-72272"

I tried this:

print [(a[0],-a[1] for a in x.split(',')) for x in e]

But it doesn't work. Can anyone suggest why or suggest an alternative
way? The text strings are significantly bigger than this so performance
is important.

It has several syntax errors; (a[0],-a[1] for a in x.split(',')) is not a
valid expression because list comprehensions are bracketed by square
brackets, not parentheses. Also, the first part of a list comprehension,
the expression to calculate each element, needs to be in parens to if it has
a comma, so that the parser can disambiguate it from an ordinary list.

I also don't know where you got 'e' from. Is it 's', or 's.split()'?

If list comprenhensions grow unwieldy, just use a for loop. They're
probably easier to read than a list comprehension that takes you ten minutes
to concoct, and performance is almost identical. For the sake of answering
your question, though, here's a expression that does what you ask:
'114320,-69808 114272,-69920 113568,-71600 113328,-72272'

You could do this with list comprehensions, e.g.:
' '.join(['%s,-%s' % tuple(x) for x in [pairs.split(',') for pairs in s.split(' ')]])
'114320,-69808 114272,-69920 113568,-71600 113328,-72272'

But I don't really see the point, given the way you've described the
problem.

-Andrew.
 
A

Aahz

Trying to change a string(x,y values) such as :

s = "114320,69808 114272,69920 113568,71600 113328,72272"

into (x,-y):

out = "114320,-69808 114272,-69920 113568,-71600 113328,-72272"

I tried this:

print [(a[0],-a[1] for a in x.split(',')) for x in e]

But it doesn't work. Can anyone suggest why or suggest an alternative
way? The text strings are significantly bigger than this so performance
is important.

When in doubt, break a problem into smaller steps. Let me play Socrates
for a minute: what's the first step in working with your dataset?
 
G

Guy Robinson

This works I was just wondering if something could be written more
concisely and hopefully faster:

s = "114320,69808 114272,69920 113568,71600 113328,72272"
e = s.split(' ')
out =''
for d in e:
d =d.split(',')
out +='%s,%d ' %(d[0],-int(d[1]))
print out

Guy
Guy Robinson said:
Trying to change a string(x,y values) such as :

s = "114320,69808 114272,69920 113568,71600 113328,72272"

into (x,-y):

out = "114320,-69808 114272,-69920 113568,-71600 113328,-72272"

I tried this:

print [(a[0],-a[1] for a in x.split(',')) for x in e]

But it doesn't work. Can anyone suggest why or suggest an alternative
way? The text strings are significantly bigger than this so performance
is important.


When in doubt, break a problem into smaller steps. Let me play Socrates
for a minute: what's the first step in working with your dataset?
 
S

Shalabh Chaturvedi

Guy said:
This works I was just wondering if something could be written more
concisely and hopefully faster:
s = "114320,69808 114272,69920 113568,71600 113328,72272"
e = s.split(' ')
out =''

outl = []
for d in e:
d =d.split(',')
out +='%s,%d ' %(d[0],-int(d[1]))

outl.append(s) # where s is the string you construct
out = ' '.join(outl)
print out

Guy

It's faster to collect strings in a list and join them later than to
concatenate strings one by one.

Also, do you have to convert d[1] to int? If you are sure that it is
always a positive integer, you can do '%s,-%s' % (d[0],d[1]).

In fact you could even try to replace ',' with ',-' instead of splitting
the string at all. Of course it depends on what the format of your
incoming string is.
 
A

Aahz

This works I was just wondering if something could be written more
concisely and hopefully faster:

s = "114320,69808 114272,69920 113568,71600 113328,72272"
e = s.split(' ')
out =''
for d in e:
d =d.split(',')
out +='%s,%d ' %(d[0],-int(d[1]))
print out

Performance I can understand (which Shalabh addressed quite nicely), but
why do you care about compressing the source code? This is simple,
straightforward, and easy to read; surely that's more important than
saving a few bytes?
 
T

Tim Roberts

Guy Robinson said:
This works I was just wondering if something could be written more
concisely and hopefully faster:

s = "114320,69808 114272,69920 113568,71600 113328,72272"
e = s.split(' ')
out =''
for d in e:
d =d.split(',')
out +='%s,%d ' %(d[0],-int(d[1]))
print out

Well, why not the more obvious: s.replace(',',',-')
 
P

Peter Otten

Tim said:
Guy Robinson said:
This works I was just wondering if something could be written more
concisely and hopefully faster:

s = "114320,69808 114272,69920 113568,71600 113328,72272"
e = s.split(' ')
out =''
for d in e:
d =d.split(',')
out +='%s,%d ' %(d[0],-int(d[1]))
print out

Well, why not the more obvious: s.replace(',',',-')

But beware negative numbers:
Traceback (most recent call last):

Therefore at least

As to robustness, the OP relying on commas not being followed by a space
seems dangerous, too, if the original data is created manually.

Peter
 
R

Ryan Paul

Hello,

Trying to change a string(x,y values) such as :

s = "114320,69808 114272,69920 113568,71600 113328,72272"

into (x,-y):

out = "114320,-69808 114272,-69920 113568,-71600 113328,-72272"

I tried this:

print [(a[0],-a[1] for a in x.split(',')) for x in e]

But it doesn't work. Can anyone suggest why or suggest an alternative
way? The text strings are significantly bigger than this so performance
is important.

TIA,

Guy

this works:

s = "114320,69808 114272,69920 113568,71600 113328,72272"

o = [(int(a[0]),-int(a[1])) for a in [b.split(',') for b in s.split(' ')]]
print o

[(114320, -69808), (114272, -69920), (113568, -71600), (113328, -72272)]
 
G

Guy Robinson

s.replace(',',',-') HA!!:)

Thanks Andrew. As usual making it more complicated than it needs to be...

Guy

Andrew said:
Hello,

Trying to change a string(x,y values) such as :

s = "114320,69808 114272,69920 113568,71600 113328,72272"

into (x,-y):

out = "114320,-69808 114272,-69920 113568,-71600 113328,-72272"

I tried this:

print [(a[0],-a[1] for a in x.split(',')) for x in e]

But it doesn't work. Can anyone suggest why or suggest an alternative
way? The text strings are significantly bigger than this so performance
is important.


It has several syntax errors; (a[0],-a[1] for a in x.split(',')) is not a
valid expression because list comprehensions are bracketed by square
brackets, not parentheses. Also, the first part of a list comprehension,
the expression to calculate each element, needs to be in parens to if it has
a comma, so that the parser can disambiguate it from an ordinary list.

I also don't know where you got 'e' from. Is it 's', or 's.split()'?

If list comprenhensions grow unwieldy, just use a for loop. They're
probably easier to read than a list comprehension that takes you ten minutes
to concoct, and performance is almost identical. For the sake of answering
your question, though, here's a expression that does what you ask:


'114320,-69808 114272,-69920 113568,-71600 113328,-72272'

You could do this with list comprehensions, e.g.:

' '.join(['%s,-%s' % tuple(x) for x in [pairs.split(',') for pairs in s.split(' ')]])

'114320,-69808 114272,-69920 113568,-71600 113328,-72272'

But I don't really see the point, given the way you've described the
problem.

-Andrew.
 
D

David MacQuigg

Hello,

Trying to change a string(x,y values) such as :

s = "114320,69808 114272,69920 113568,71600 113328,72272"

into (x,-y):

out = "114320,-69808 114272,-69920 113568,-71600 113328,-72272"

I tried this:

print [(a[0],-a[1] for a in x.split(',')) for x in e]

But it doesn't work. Can anyone suggest why or suggest an alternative
way? The text strings are significantly bigger than this so performance
is important.

Seems like this is a very common problem, needing to process a
substring within a long list of strings. I like the way Ruby handles
these problems. Maybe a future version of Python could do this:

print s.split(' ').map().split(',').reflecty().join(' ')

You would need to define the reflecty() function, but the others
should be standard. Depending on how much variation you expect in the
input data, reflecty() could do whatever checking is necessry to avoid
the problems other posters have mentioned. Assuming the inputs are
valid string representations of numbers (i.e. no double minuses,
etc.), a simple definition could be:

def reflecty():
x,y = __self__ # a two-string list
if y[0] == '-':
return [ x, y[1:] ]
else:
return [ x, '-' + y ]

The above syntax is neither Ruby nor Python, but the idea of handling
complex sequences of string operations step-by-step, left-to-right was
inspired by Ruby. See http://userlinux.com/cgi-bin/wiki.pl?RubyPython
for a comparison of Ruby and Python string operations.

-- Dave
 
C

Christopher Barker

if you can count on there being no spaces between the x,y pairs, this works:

" ".join([ "%s,%i"%(y[0], -int(y[1]) ) for y in [x.split(",") for x in
s.split()] ])

Though I don't think I'd do it as a one liner.

-Chris


--
Christopher Barker, Ph.D.
Oceanographer

NOAA/OR&R/HAZMAT (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

(e-mail address removed)
 

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

No members online now.

Forum statistics

Threads
474,197
Messages
2,571,040
Members
47,635
Latest member
SkyePurves

Latest Threads

Top