Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #77160 > unrolled thread

python string, best way to concat

Started bydennisearlevans@gmail.com
First post2014-08-27 13:31 -0700
Last post2014-08-28 15:48 +0100
Articles 15 — 11 participants

Back to article view | Back to comp.lang.python


Contents

  python string, best way to concat dennisearlevans@gmail.com - 2014-08-27 13:31 -0700
    Re: python string, best way to concat Dan Stromberg <drsalists@gmail.com> - 2014-08-27 15:30 -0700
    Re: python string, best way to concat Peter Otten <__peter__@web.de> - 2014-08-28 00:34 +0200
    Re: python string, best way to concat MRAB <python@mrabarnett.plus.com> - 2014-08-27 23:42 +0100
    Re: python string, best way to concat Tim Chase <python.list@tim.thechases.com> - 2014-08-27 17:44 -0500
    Re: python string, best way to concat Chris Angelico <rosuav@gmail.com> - 2014-08-28 08:55 +1000
    Re: python string, best way to concat Peter Otten <__peter__@web.de> - 2014-08-28 00:59 +0200
    Re: python string, best way to concat MRAB <python@mrabarnett.plus.com> - 2014-08-28 08:12 +0100
    Re: python string, best way to concat peter <peter.mosley@talk21.com> - 2014-08-28 01:30 -0700
      Re: python string, best way to concat Marko Rauhamaa <marko@pacujo.net> - 2014-08-28 11:34 +0300
      Re: python string, best way to concat Mark Lawrence <breamoreboy@yahoo.co.uk> - 2014-08-28 09:43 +0100
      Re: python string, best way to concat Chris Angelico <rosuav@gmail.com> - 2014-08-28 18:58 +1000
      Re: python string, best way to concat Roy Smith <roy@panix.com> - 2014-08-28 08:08 -0400
        Re: python string, best way to concat Mihamina Rakotomandimby <mihamina.rakotomandimby@rktmb.org> - 2014-08-28 15:19 +0300
        Re: python string, best way to concat Mark Lawrence <breamoreboy@yahoo.co.uk> - 2014-08-28 15:48 +0100

#77160 — python string, best way to concat

Fromdennisearlevans@gmail.com
Date2014-08-27 13:31 -0700
Subjectpython string, best way to concat
Message-ID<55bab2a0-e0bc-4398-90b4-c9937498f5d8@googlegroups.com>
  Hi,

  Sorry about the simple question but I am very new to Python. 

  Anyway, I have a function that will be used to call a stored procedure and I need to format the string with the correct number of parameter markers for the ODBC driver, fairly standard stuff.   

  What I have works but looks ugly, is there a better way to build or concatenate a string or is a list or a tuple a better option?

the function looks like this

  def callSp(self, schema, spName) :
   sqlCode = "{call " + schema + "." + spName + "("
   par_Markers = ""
   y = len(self.param)
   x = 0
   while x < y :
     par_Markers = par_Markers.join("?")
     if (x < y - 1) :
       par_Markers = par_Markers.join(", ")
     x += 1
   self.cmdText = sqlCode + par_Markers + ")}"
   self.ExecuteCursor()

   return

self.param is a list of parameters.  sself.cmdText is the text that will be used to call the stored procedure.

the function would be called like this

  class.AddParameter(some value 1)
  class.AddParameter(some value 2) 
  callSp("schemaName", "storedProcedureName")
  
  the self.cmdText will look like this just before the ExecuteCursor call 

  "{call schemaName.StoredProcedureName(?, ?)}"

  the code works, but as I said is a bit ugly, is there better methods?

  thanks 

  Dennis
  

[toc] | [next] | [standalone]


#77166

FromDan Stromberg <drsalists@gmail.com>
Date2014-08-27 15:30 -0700
Message-ID<mailman.13527.1409178652.18130.python-list@python.org>
In reply to#77160
On Wed, Aug 27, 2014 at 1:31 PM,  <dennisearlevans@gmail.com> wrote:
>
>   Hi,
>
>   Sorry about the simple question but I am very new to Python.
>
>   Anyway, I have a function that will be used to call a stored procedure and I need to format the string with the correct number of parameter markers for the ODBC driver, fairly standard stuff.
>
>   What I have works but looks ugly, is there a better way to build or concatenate a string or is a list or a tuple a better option?
>
> the function looks like this
>
>   def callSp(self, schema, spName) :
>    sqlCode = "{call " + schema + "." + spName + "("
>    par_Markers = ""
>    y = len(self.param)
>    x = 0
>    while x < y :
>      par_Markers = par_Markers.join("?")
>      if (x < y - 1) :
>        par_Markers = par_Markers.join(", ")
>      x += 1
>    self.cmdText = sqlCode + par_Markers + ")}"
>    self.ExecuteCursor()
>
>    return
>
> self.param is a list of parameters.  sself.cmdText is the text that will be used to call the stored procedure.
>
> the function would be called like this
>
>   class.AddParameter(some value 1)
>   class.AddParameter(some value 2)
>   callSp("schemaName", "storedProcedureName")
>
>   the self.cmdText will look like this just before the ExecuteCursor call
>
>   "{call schemaName.StoredProcedureName(?, ?)}"
>
>   the code works, but as I said is a bit ugly, is there better methods?
>
>   thanks
>
>   Dennis

If you have a constant number of things to put in a string, often 'abc
{} ghi {}'.format('def', 'jkl') is good - this will produce 'abc def
ghi jkl'.

If you have a variable number of things to put in a string, toss them
all in a list, and join them:
list_ = ['abc, 'def', 'ghi']
for number in range(4):
   list_.append(str(number))
list_.extend(['jkl', 'mno')

# elements of the list will be separated by one space:
string = ' '.join(list_)

[toc] | [prev] | [next] | [standalone]


#77167

FromPeter Otten <__peter__@web.de>
Date2014-08-28 00:34 +0200
Message-ID<mailman.13528.1409178864.18130.python-list@python.org>
In reply to#77160
dennisearlevans@gmail.com wrote:

> 
>   Hi,
> 
>   Sorry about the simple question but I am very new to Python.
> 
>   Anyway, I have a function that will be used to call a stored procedure
>   and I need to format the string with the correct number of parameter
>   markers for the ODBC driver, fairly standard stuff.
> 
>   What I have works but looks ugly, is there a better way to build or
>   concatenate a string or is a list or a tuple a better option?
> 
> the function looks like this
> 
>   def callSp(self, schema, spName) :
>    sqlCode = "{call " + schema + "." + spName + "("
>    par_Markers = ""
>    y = len(self.param)
>    x = 0
>    while x < y :
>      par_Markers = par_Markers.join("?")
>      if (x < y - 1) :
>        par_Markers = par_Markers.join(", ")
>      x += 1
>    self.cmdText = sqlCode + par_Markers + ")}"
>    self.ExecuteCursor()
> 
>    return
> 
> self.param is a list of parameters.  sself.cmdText is the text that will
> be used to call the stored procedure.
> 
> the function would be called like this
> 
>   class.AddParameter(some value 1)
>   class.AddParameter(some value 2)
>   callSp("schemaName", "storedProcedureName")
>   
>   the self.cmdText will look like this just before the ExecuteCursor call
> 
>   "{call schemaName.StoredProcedureName(?, ?)}"
> 
>   the code works, but as I said is a bit ugly, is there better methods?

If I understand you correctly you have two problems.

(1) build a string from a few parts. You can use string formatting for that:

>>> "It's a {size} {animal}".format(size="big", animal="bird")
"It's a big bird"

You can escape { and } by repeating them:

>>> "{{It's a {size} {animal}}}".format(size="big", animal="bird")
"{It's a big bird}"

(2) Build a string containing a comma-separated list with a varying number 
of question marks. That's easy with str.join():

>>> ", ".join(7*"?")
'?, ?, ?, ?, ?, ?, ?'

The complete method may become

    def callSp(self, schema, spName) :
        qm = ", ".join("?"*len(self.param))
        self.cmdText = "{{call {schema}.{procname} ({qm})}}".format(
            schema=schema, procname=spName, qm=qm)
        self.ExecuteCursor()

... but please consider adopting the conventions recommended in the style 
guide

http://legacy.python.org/dev/peps/pep-0008/

before you write a significant amount of Python code.

[toc] | [prev] | [next] | [standalone]


#77169

FromMRAB <python@mrabarnett.plus.com>
Date2014-08-27 23:42 +0100
Message-ID<mailman.13529.1409179359.18130.python-list@python.org>
In reply to#77160
On 2014-08-27 21:31, dennisearlevans@gmail.com wrote:
>
>    Hi,
>
>    Sorry about the simple question but I am very new to Python.
>
>    Anyway, I have a function that will be used to call a stored procedure and I need to format the string with the correct number of parameter markers for the ODBC driver, fairly standard stuff.
>
>    What I have works but looks ugly, is there a better way to build or concatenate a string or is a list or a tuple a better option?
>
> the function looks like this
>
>    def callSp(self, schema, spName) :
>     sqlCode = "{call " + schema + "." + spName + "("
>     par_Markers = ""
>     y = len(self.param)
>     x = 0
>     while x < y :
>       par_Markers = par_Markers.join("?")
>       if (x < y - 1) :
>         par_Markers = par_Markers.join(", ")
>       x += 1
>     self.cmdText = sqlCode + par_Markers + ")}"
>     self.ExecuteCursor()
>
>     return
>
How many parameters are there? len(self.param)

Make that many placeholders and then join them together with commas:

', '.join(['?'] * len(self.param))

> self.param is a list of parameters.  sself.cmdText is the text that will be used to call the stored procedure.
>
> the function would be called like this
>
>    class.AddParameter(some value 1)
>    class.AddParameter(some value 2)
>    callSp("schemaName", "storedProcedureName")
>
>    the self.cmdText will look like this just before the ExecuteCursor call
>
>    "{call schemaName.StoredProcedureName(?, ?)}"
>
>    the code works, but as I said is a bit ugly, is there better methods?
>

[toc] | [prev] | [next] | [standalone]


#77170

FromTim Chase <python.list@tim.thechases.com>
Date2014-08-27 17:44 -0500
Message-ID<mailman.13530.1409179587.18130.python-list@python.org>
In reply to#77160
On 2014-08-27 23:42, MRAB wrote:
> How many parameters are there? len(self.param)
> 
> Make that many placeholders and then join them together with commas:
> 
> ', '.join(['?'] * len(self.param))

I prefer the clarity of Peter Otten's suggestion of

  ', '.join('?' * len(self.param))

over the mild obscurity of putting it in a list before multiplying.

-tkc



[toc] | [prev] | [next] | [standalone]


#77173

FromChris Angelico <rosuav@gmail.com>
Date2014-08-28 08:55 +1000
Message-ID<mailman.13533.1409180134.18130.python-list@python.org>
In reply to#77160
On Thu, Aug 28, 2014 at 8:44 AM, Tim Chase
<python.list@tim.thechases.com> wrote:
> On 2014-08-27 23:42, MRAB wrote:
>> How many parameters are there? len(self.param)
>>
>> Make that many placeholders and then join them together with commas:
>>
>> ', '.join(['?'] * len(self.param))
>
> I prefer the clarity of Peter Otten's suggestion of
>
>   ', '.join('?' * len(self.param))
>
> over the mild obscurity of putting it in a list before multiplying.

Actually, I'd go the other way. This code has a possibly-surprising
limitation: it works only if the replicated string is one character
long, and in Python 3, that really does mean character, not byte. Of
course, Python experts know that it works on string iterability, and
know exactly why b'?' wouldn't work there, but putting it in a list
solves both problems.

So, I'd say the ['?'] code is less fragile.

ChrisA

[toc] | [prev] | [next] | [standalone]


#77174

FromPeter Otten <__peter__@web.de>
Date2014-08-28 00:59 +0200
Message-ID<mailman.13534.1409180390.18130.python-list@python.org>
In reply to#77160
Tim Chase wrote:

> On 2014-08-27 23:42, MRAB wrote:
>> How many parameters are there? len(self.param)
>> 
>> Make that many placeholders and then join them together with commas:
>> 
>> ', '.join(['?'] * len(self.param))
> 
> I prefer the clarity of Peter Otten's suggestion of
> 
>   ', '.join('?' * len(self.param))
> 
> over the mild obscurity of putting it in a list before multiplying.

As long as the OP doesn't try to transfer this to other paramstyles:

>>> ", ".join(["%s"]*3)
'%s, %s, %s'
>>> ", ".join("%s"*3) # OOPS
'%, s, %, s, %, s'

[toc] | [prev] | [next] | [standalone]


#77186

FromMRAB <python@mrabarnett.plus.com>
Date2014-08-28 08:12 +0100
Message-ID<mailman.13543.1409209950.18130.python-list@python.org>
In reply to#77160
On 2014-08-27 23:59, Peter Otten wrote:
> Tim Chase wrote:
>
>> On 2014-08-27 23:42, MRAB wrote:
>>> How many parameters are there? len(self.param)
>>>
>>> Make that many placeholders and then join them together with
>>> commas:
>>>
>>> ', '.join(['?'] * len(self.param))
>>
>> I prefer the clarity of Peter Otten's suggestion of
>>
>> ', '.join('?' * len(self.param))
>>
>> over the mild obscurity of putting it in a list before
>> multiplying.
>
> As long as the OP doesn't try to transfer this to other paramstyles:
>
 >>>> ", ".join(["%s"]*3)
 > '%s, %s, %s'
 >>>> ", ".join("%s"*3) # OOPS
 > '%, s, %, s, %, s'
 >
I chose the list form for just this reason, because the OP said he was
"very new to Python".

[toc] | [prev] | [next] | [standalone]


#77187

Frompeter <peter.mosley@talk21.com>
Date2014-08-28 01:30 -0700
Message-ID<63bdccb4-9e34-4e40-b07d-14342e21815f@googlegroups.com>
In reply to#77160
I used to struggle with the concept of ''.join(('hello ','world')) - it seemed so convoluted compared with the intuitive 'hello '+'world', and I could never remember the syntax.  Also, for the strings I was generally using the performance penalty was infinitesimal, so I was just adding complexity for the sake of the abstract concept of a more 'pythonic' style.

Obviously this isn't going to change, but for concatenating short strings a and b is there any practical reason to avoid a+b?

Peter

[toc] | [prev] | [next] | [standalone]


#77188

FromMarko Rauhamaa <marko@pacujo.net>
Date2014-08-28 11:34 +0300
Message-ID<87wq9tf1wc.fsf@elektro.pacujo.net>
In reply to#77187
peter <peter.mosley@talk21.com>:

> Obviously this isn't going to change, but for concatenating short
> strings a and b is there any practical reason to avoid a+b?

Often, no. The biggest penalty is visual. For example, I would prefer
this:

    "{}/{}".format(prefix, suffix)

over

    prefix + "/" + suffix


Really, I would and do.


Marko

[toc] | [prev] | [next] | [standalone]


#77189

FromMark Lawrence <breamoreboy@yahoo.co.uk>
Date2014-08-28 09:43 +0100
Message-ID<mailman.13545.1409215403.18130.python-list@python.org>
In reply to#77187
On 28/08/2014 09:30, peter wrote:
> I used to struggle with the concept of ''.join(('hello ','world')) - it seemed so convoluted compared with the intuitive 'hello '+'world', and I could never remember the syntax.  Also, for the strings I was generally using the performance penalty was infinitesimal, so I was just adding complexity for the sake of the abstract concept of a more 'pythonic' style.
>
> Obviously this isn't going to change, but for concatenating short strings a and b is there any practical reason to avoid a+b?
>
> Peter
>

Please quote context, there's some smart people on this list but none of 
them are mind readers :)

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence

[toc] | [prev] | [next] | [standalone]


#77191

FromChris Angelico <rosuav@gmail.com>
Date2014-08-28 18:58 +1000
Message-ID<mailman.13547.1409216298.18130.python-list@python.org>
In reply to#77187
On Thu, Aug 28, 2014 at 6:43 PM, Mark Lawrence <breamoreboy@yahoo.co.uk> wrote:
> On 28/08/2014 09:30, peter wrote:
>>
>> I used to struggle with the concept of ''.join(('hello ','world')) - it
>> seemed so convoluted compared with the intuitive 'hello '+'world', and I
>> could never remember the syntax.  Also, for the strings I was generally
>> using the performance penalty was infinitesimal, so I was just adding
>> complexity for the sake of the abstract concept of a more 'pythonic' style.
>>
>> Obviously this isn't going to change, but for concatenating short strings
>> a and b is there any practical reason to avoid a+b?
>>
>> Peter
>>
>
> Please quote context, there's some smart people on this list but none of
> them are mind readers :)

Speak for yourself! I play a mind reader on Threshold RPG (in fact,
one of the highest level psions on the game), and several of my
brothers tell me I can pull the same tricks in real life. Or maybe I'm
just really good at knowing what problems they're having, even before
they recognize the problems themselves...

But Peter, no - no reason to avoid it for concatenating two strings.
The advantages of join() are visible when you have huge numbers of
strings; plus it's more readable than repeating a separator lots of
times, especially if you're working with variable numbers of list
elements:

https://github.com/Rosuav/runningtime/blob/master/runningtime.py#L211

The debug info is collected in a list (appending each item, and quite
a few of them are elided if they're some kind of default), and then
they're joined with ', ' as the separator. I could use string
appending for that, but there's no point; it's more readable this way.
Performance doesn't matter at all here, just readability.

ChrisA

[toc] | [prev] | [next] | [standalone]


#77201

FromRoy Smith <roy@panix.com>
Date2014-08-28 08:08 -0400
Message-ID<roy-87A30C.08075228082014@news.panix.com>
In reply to#77187
In article <63bdccb4-9e34-4e40-b07d-14342e21815f@googlegroups.com>,
 peter <peter.mosley@talk21.com> wrote:

> I used to struggle with the concept of ''.join(('hello ','world')) - it 
> seemed so convoluted compared with the intuitive 'hello '+'world', and I 
> could never remember the syntax.  Also, for the strings I was generally using 
> the performance penalty was infinitesimal, so I was just adding complexity 
> for the sake of the abstract concept of a more 'pythonic' style.
> 
> Obviously this isn't going to change, but for concatenating short strings a 
> and b is there any practical reason to avoid a+b?

For places where performance doesn't matter, string addition is just 
fine.  The computer works for you.  If you're working for the computer, 
you're doing something wrong.

That being said, join is typically used where you have a variable number 
of strings in some iterable (e.g. a list of strings).  For exactly two 
strings, I would have probably written this as:

'%s %s' % (string1, string2)

and if I really wanted to use the join syntax, I would have moved the 
delimiter (in this case, a space), into the first string:

' '.join([string1, string2])

Be aware of the various ways, then pick the one that works for you.

[toc] | [prev] | [next] | [standalone]


#77202

FromMihamina Rakotomandimby <mihamina.rakotomandimby@rktmb.org>
Date2014-08-28 15:19 +0300
Message-ID<mailman.13554.1409228332.18130.python-list@python.org>
In reply to#77201
On 08/28/2014 03:08 PM, Roy Smith wrote:
> For places where performance doesn't matter, string addition is just
> fine.  The computer works for you.  If you're working for the computer,
> you're doing something wrong.

I like this :-)

[toc] | [prev] | [next] | [standalone]


#77213

FromMark Lawrence <breamoreboy@yahoo.co.uk>
Date2014-08-28 15:48 +0100
Message-ID<mailman.13564.1409237343.18130.python-list@python.org>
In reply to#77201
On 28/08/2014 13:08, Roy Smith wrote:
> In article <63bdccb4-9e34-4e40-b07d-14342e21815f@googlegroups.com>,
>   peter <peter.mosley@talk21.com> wrote:
>
>> I used to struggle with the concept of ''.join(('hello ','world')) - it
>> seemed so convoluted compared with the intuitive 'hello '+'world', and I
>> could never remember the syntax.  Also, for the strings I was generally using
>> the performance penalty was infinitesimal, so I was just adding complexity
>> for the sake of the abstract concept of a more 'pythonic' style.
>>
>> Obviously this isn't going to change, but for concatenating short strings a
>> and b is there any practical reason to avoid a+b?
>
> For places where performance doesn't matter, string addition is just
> fine.  The computer works for you.  If you're working for the computer,
> you're doing something wrong.
>
> That being said, join is typically used where you have a variable number
> of strings in some iterable (e.g. a list of strings).  For exactly two
> strings, I would have probably written this as:
>
> '%s %s' % (string1, string2)
>
> and if I really wanted to use the join syntax, I would have moved the
> delimiter (in this case, a space), into the first string:
>
> ' '.join([string1, string2])
>
> Be aware of the various ways, then pick the one that works for you.
>

Which reminds me of 
http://code.activestate.com/recipes/577845-format_iter-easy-formatting-of-arbitrary-iterables/

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web