String building using join

G

gervaz

Hi all, I would like to ask you how I can use the more efficient join
operation in a code like this:
.... def __init__(self, v1, v2):
.... self.v1 = v1
.... self.v2 = v2
........ txt = ""
.... for x in l:
.... if x.v1 is not None:
.... txt += x.v1 + "\n"
.... if x.v2 is not None:
.... txt += x.v2 + "\n"
.... return txt
....
t1 = Test("hello", None)
t2 = Test(None, "ciao")
t3 = Test("salut", "hallo")
t = [t1, t2, t3]

prg(t)
'hello\nciao\nsalut\nhallo\n'

The idea would be create a new list with the values not None and then
use the join function... but I don't know if it is really worth it.
Any hint?
.... e = []
.... for x in l:
.... if x.v1 is not None:
.... e.append(x.v1)
.... if x.v2 is not None:
.... e.append(x.v2)
.... return "\n".join(e)
....'hello\nciao\nsalut\nhallo'

Thanks, Mattia
 
E

Emile van Sebille

... def __init__(self, v1, v2):
... self.v1 = v1
... self.v2 = v2
...... txt = ""
... for x in l:
... if x.v1 is not None:
... txt += x.v1 + "\n"
... if x.v2 is not None:
... txt += x.v2 + "\n"
... return txt
...
t1 = Test("hello", None)
t2 = Test(None, "ciao")
t3 = Test("salut", "hallo")
t = [t1, t2, t3]

prg(t)
'hello\nciao\nsalut\nhallo\n'

The idea would be create a new list with the values not None and then
use the join function... but I don't know if it is really worth it.
Any hint?
[/QUOTE]

return "\n".join([x for x in l if x])

Emile


... e = []
... for x in l:
... if x.v1 is not None:
... e.append(x.v1)
... if x.v2 is not None:
... e.append(x.v2)
... return "\n".join(e)
...'hello\nciao\nsalut\nhallo'

Thanks, Mattia
 
G

gervaz

On 12/31/2010 7:22 AM gervaz said...




Hi all, I would like to ask you how I can use the more efficient join
operation in a code like this:
class Test:
...     def __init__(self, v1, v2):
...         self.v1 = v1
...         self.v2 = v2
...
def prg(l):
...     txt = ""
...     for x in l:
...         if x.v1 is not None:
...             txt += x.v1 + "\n"
...         if x.v2 is not None:
...             txt += x.v2 + "\n"
...     return txt
...
t1 = Test("hello", None)
t2 = Test(None, "ciao")
t3 = Test("salut", "hallo")
t = [t1, t2, t3]
prg(t) 'hello\nciao\nsalut\nhallo\n'

The idea would be create a new list with the values not None and then
use the join function... but I don't know if it is really worth it.
Any hint?
def prg2(l):

             return "\n".join([x for x in l if x])

Emile


...     e = []
...     for x in l:
...         if x.v1 is not None:
...             e.append(x.v1)
...         if x.v2 is not None:
...             e.append(x.v2)
...     return "\n".join(e)
...
prg2(t) 'hello\nciao\nsalut\nhallo'

Thanks, Mattia- Nascondi testo citato

- Mostra testo citato -- Nascondi testo citato

- Mostra testo citato -

Sorry, but it does not work
.... return "\n".join([x for x in l if x])
....Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in prg3
TypeError: sequence item 0: expected str instance, Test found
 
E

Emile van Sebille

On 12/31/2010 7:22 AM gervaz said...




Hi all, I would like to ask you how I can use the more efficient join
operation in a code like this:
class Test:
... def __init__(self, v1, v2):
... self.v1 = v1
... self.v2 = v2
...
def prg(l):
... txt = ""
... for x in l:
... if x.v1 is not None:
... txt += x.v1 + "\n"
... if x.v2 is not None:
... txt += x.v2 + "\n"
... return txt
...
t1 = Test("hello", None)
t2 = Test(None, "ciao")
t3 = Test("salut", "hallo")
t = [t1, t2, t3]
prg(t)
'hello\nciao\nsalut\nhallo\n'

The idea would be create a new list with the values not None and then
use the join function... but I don't know if it is really worth it.
Any hint?
def prg2(l):

return "\n".join([x for x in l if x])

Emile


... e = []
... for x in l:
... if x.v1 is not None:
... e.append(x.v1)
... if x.v2 is not None:
... e.append(x.v2)
... return "\n".join(e)
...
prg2(t)
'hello\nciao\nsalut\nhallo'
Thanks, Mattia- Nascondi testo citato

- Mostra testo citato -- Nascondi testo citato

- Mostra testo citato -

Sorry, but it does not work[/QUOTE]

Oh -- you want a working solution, not a hint? OK.

class Test:
def __init__(self, v1, v2):
self.v1 = v1
self.v2 = v2


t1 = Test("hello", None)
t2 = Test(None, "ciao")
t3 = Test("salut", "hallo")
t = [t1, t2, t3]


"\n".join([y for x in t for y in [x.v1,x.v2] if y])

Emile
... return "\n".join([x for x in l if x])
...Traceback (most recent call last):
File "<stdin>", line 1, in<module>
File "<stdin>", line 2, in prg3
TypeError: sequence item 0: expected str instance, Test found
 
G

gervaz

On 1/2/2011 9:43 AM gervaz said...




On 12/31/2010 7:22 AM gervaz said...
Hi all, I would like to ask you how I can use the more efficient join
operation in a code like this:
class Test:
...     def __init__(self, v1, v2):
...         self.v1 = v1
...         self.v2 = v2
...
def prg(l):
...     txt = ""
...     for x in l:
...         if x.v1 is not None:
...             txt += x.v1 + "\n"
...         if x.v2 is not None:
...             txt += x.v2 + "\n"
...     return txt
...
t1 = Test("hello", None)
t2 = Test(None, "ciao")
t3 = Test("salut", "hallo")
t = [t1, t2, t3]
prg(t)
'hello\nciao\nsalut\nhallo\n'
The idea would be create a new list with the values not None and then
use the join function... but I don't know if it is really worth it.
Any hint?
def prg2(l):
              return "\n".join([x for x in l if x])
Emile
...     e = []
...     for x in l:
...         if x.v1 is not None:
...             e.append(x.v1)
...         if x.v2 is not None:
...             e.append(x.v2)
...     return "\n".join(e)
...
prg2(t)
'hello\nciao\nsalut\nhallo'
Thanks, Mattia- Nascondi testo citato
- Mostra testo citato -- Nascondi testo citato
- Mostra testo citato -
Sorry, but it does not work

Oh -- you want a working solution, not a hint?  OK.

class Test:
      def __init__(self, v1, v2):
          self.v1 = v1
          self.v2 = v2

t1 = Test("hello", None)
t2 = Test(None, "ciao")
t3 = Test("salut", "hallo")
t = [t1, t2, t3]

"\n".join([y for x in t for y in [x.v1,x.v2] if y])

Emile




def prg3(l):
...     return "\n".join([x for x in l if x])
...
Traceback (most recent call last):
   File "<stdin>", line 1, in<module>
   File "<stdin>", line 2, in prg3
TypeError: sequence item 0: expected str instance, Test found- Nascondi testo citato

- Mostra testo citato -- Nascondi testo citato

- Mostra testo citato -

Thanks Emile, despite that now the solution runs in quadratic time I
guess. I could also provide a __str__(self) representation, but in my
real code I don't have access to the class. Also using str() on an
empty object (i.e. None), the representation is 'None'.

Ciao,

Mattia
 
G

gervaz

On 1/2/2011 9:43 AM gervaz said...
On 12/31/2010 7:22 AM gervaz said...
Hi all, I would like to ask you how I can use the more efficient join
operation in a code like this:
class Test:
...     def __init__(self, v1, v2):
...         self.v1 = v1
...         self.v2 = v2
...
def prg(l):
...     txt = ""
...     for x in l:
...         if x.v1 is not None:
...             txt += x.v1 + "\n"
...         if x.v2 is not None:
...             txt += x.v2 + "\n"
...     return txt
...
t1 = Test("hello", None)
t2 = Test(None, "ciao")
t3 = Test("salut", "hallo")
t = [t1, t2, t3]
prg(t)
'hello\nciao\nsalut\nhallo\n'
The idea would be create a new list with the values not None and then
use the join function... but I don't know if it is really worth it.
Any hint?
def prg2(l):
              return "\n".join([x for x in l if x])
Emile
...     e = []
...     for x in l:
...         if x.v1 is not None:
...             e.append(x.v1)
...         if x.v2 is not None:
...             e.append(x.v2)
...     return "\n".join(e)
...
prg2(t)
'hello\nciao\nsalut\nhallo'
Thanks, Mattia- Nascondi testo citato
- Mostra testo citato -- Nascondi testo citato
- Mostra testo citato -
Sorry, but it does not work
Oh -- you want a working solution, not a hint?  OK.
class Test:
      def __init__(self, v1, v2):
          self.v1 = v1
          self.v2 = v2
t1 = Test("hello", None)
t2 = Test(None, "ciao")
t3 = Test("salut", "hallo")
t = [t1, t2, t3]
"\n".join([y for x in t for y in [x.v1,x.v2] if y])
def prg3(l):
...     return "\n".join([x for x in l if x])
...
prg3(t)
Traceback (most recent call last):
   File "<stdin>", line 1, in<module>
   File "<stdin>", line 2, in prg3
TypeError: sequence item 0: expected str instance, Test found- Nascondi testo citato
- Mostra testo citato -- Nascondi testo citato
- Mostra testo citato -

Thanks Emile, despite that now the solution runs in quadratic time I
guess. I could also provide a __str__(self) representation, but in my
real code I don't have access to the class. Also using str() on an
empty object (i.e. None), the representation is 'None'.

Ciao,

Mattia- Nascondi testo citato

- Mostra testo citato -

And this one is another working solution...
.... s = []
.... for x in l:
.... s.extend(set([x.v1, x.v2]) - set([None]))
.... return "\n".join(s)
....'hello\nciao\nhallo\nsalut'

My original question was just related to the fact that I read that the
string concatenation in expensive and it sould be used the join()
function but now probably it is better to stick with the first
implementation, the simplest one.

Ciao,

Mattia
 
A

Alexander Gattin

Hello,

def prg3(l):
return '\n'.join([str(x) for x in l if x])

just one fix (one fix one fix one fix):
return '\n'.join([str(x) for x in l if x is not None])
 
K

Kushal Kumaran

<snip>

class Test:
      def __init__(self, v1, v2):
          self.v1 = v1
          self.v2 = v2

t1 = Test("hello", None)
t2 = Test(None, "ciao")
t3 = Test("salut", "hallo")
t = [t1, t2, t3]

"\n".join([y for x in t for y in [x.v1,x.v2] if y])
<snip>

Thanks Emile, despite that now the solution runs in quadratic time I
guess. I could also provide a __str__(self) representation, but in my
real code I don't have access to the class. Also using str() on an
empty object (i.e. None), the representation is 'None'.

Since no one else has mentioned it, I'll just point out that Emile's
solution does not run in quadratic time. It has the same number of
operations as the originally posted code.

That str(None) results in "None" is not a problem because of the "if
y" test in the list comprehension.
 
A

Arnaud Delobelle

gervaz said:
Hi all, I would like to ask you how I can use the more efficient join
operation in a code like this:

... def __init__(self, v1, v2):
... self.v1 = v1
... self.v2 = v2
...
... txt = ""
... for x in l:
... if x.v1 is not None:
... txt += x.v1 + "\n"
... if x.v2 is not None:
... txt += x.v2 + "\n"
... return txt
...

You can change the prg() function above slightly to make it a generator
function:

def genprg(l):
for x in l:
if x.v1 is not None:
yield x.v1
if x.v2 is not None:
yield x.v2

Then you can rewrite prg using join:

def prg(l):
return '\n'.join(genprg(l))

This way you save yourself from creating a list. I know this is not the
one liner that others have suggested but it shows a general way of
transforming a piece of code in order to make use of generator functions.
 

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,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top