6

I have a list :list = [1,2,3]. And I would like to convert that into a string with parentheses: string = (1,2,3).

Currently I am using string replace string = str(list).replace('[','(').replace(']',')'). But I think there is a better way using regex.sub. But I have no idea how to do it. Thanks a lot

2
  • 1
    Nope - what you are doing looks good to me. Commented Feb 19, 2013 at 2:59
  • str.replace(old, new[, max]) Commented Feb 19, 2013 at 3:01

7 Answers 7

18

If you do indeed have a list, then:

>>> s  = [1,2,3]
>>> str(tuple(s))
'(1, 2, 3)'
Sign up to request clarification or add additional context in comments.

4 Comments

Should have read closer. I just assumed that OP had a string that was formatted like a list. +1. This is the way I would do it in my real code I think.
But I have another one with string, then it doesn't work so well. >>> s = ['1'] >>> str(tuple(s)) "('1',)"
str(tuple(s)).rstrip(',)') + ')' '(1)'
Doesn't work for list with single element. It will add a trailing comma like "(1,)"
7

You could use string.maketrans instead -- I'm betting it runs faster than a sequence of str.replace and it scales better to more single character replacements.

>>> import string
>>> table = string.maketrans('[]','()')
>>> s = "[1, 2, 3, 4]"
>>> s.translate(table)
'(1, 2, 3, 4)'

You can even use this to remove characters from the original string by passing an optional second argument to str.translate:

>>> s = str(['1','2'])
>>> s
"['1', '2']"
>>> s.translate(table,"'")
'(1, 2)'

In python3.x, the string module is gone and you gain access to maketrans via the str builtin:

table = str.maketrans('[]','()')

2 Comments

It doesn't work so well on list of string. >>>s = ['1'] >>> str(s).translate(table) "('1')"
@Winston -- It actually handles that quite easily. See my edit.
3

There are a billion ways to do this, as demonstrated by all the answers. Here's another one:

my_list = [1,2,3]
my_str = "(%s)" % str(my_list).strip('[]')

or make it recyclable:

list_in_parens = lambda l: "(%s)" % str(l).strip('[]')
my_str = list_in_parens(my_list)

Comments

1

str([1,2,3]).replace('[','(').replace(']',')')

Should work for you well, and it is forward and backward compatible as far as I know.

as far as re-usability, you can use the following function for multiple different types of strings to change what they start and end with:

def change(str_obj,start,end):
    if isinstance(str_obj,str) and isinstance(start,str) and isinstance(end,str):
        pass
    else:
        raise Exception("Error, expecting a 'str' objects, got %s." % ",".join(str(type(x)) for x in [str_obj,start,end]))
    if len(str_obj)>=2:
        temp=list(str_obj)
        temp[0]=start
        temp[len(str_obj)-1]=end
        return "".join(temp)
    else:
         raise Exception("Error, string size must be greater than or equal to 2. Got a length of: %s" % len(str_obj))

1 Comment

Yes this works perfectly. But I want a better implementation. Maybe regex is a good way.
1

If you really want to use regex I guess this would work. But the other posted solutions are probably more efficient and/or easy to use.

import re

string = str(list)
re.sub(r"[\[]", "(", string)
re.sub(r"[\]]", ")", string)

@mgilson something like this you mean?

def replace_stuff(string):
    string_list = list(string)
    pattern = re.compile(r"[\[\]]")
    result = re.match(pattern, string)
    for i in range(len(result.groups())):
        bracket = result.group(i)
        index = bracket.start()
        print(index)
        if bracket == "[":
            string_list[index] = "("
        else:
            string_list[index] = ")"

    return str(string_list)

It doesn't quite work, for some reason len(result.groups()) is always 0 even though the regex should find matches. So couldn't test whether this is faster but because I couldn't get it to work I couldn't test it. I have to leave for bed now so if someone can fix this go ahead.

4 Comments

Great. Is it possible to do it on 1 line?
I'm no regex expert at all but I don't think so. Because you want to replace with two different strings "(" and ")" and you can only replace one regex with one string using re.sub.
@DaanLubbers -- You could define a function to pass to re.sub which would then take the match object and decide whether to substitute a '(' or a ')'. It might even be slightly more efficient (you'd need to timeit to find out), but it would be slightly more code as you'd need to define the function properly, etc, etc..
Updated the post with a function which should do what you asked (I think). I have no clue if it could be fast as I don't know how long the re functions take but it at least takes way more effort to code. I am quite intrigued now whether this is faster or not. Sadly as you can read I don't know why it doesn't work as is and have to go, maybe you can have a swing at it?
1

All you need is:

"(" + strng.strip('[]') + ")"

It works for both single element and multi-element lists.

>>> lst = [1,2,3]
>>> strng = str(lst)
>>> "(" + strng.strip('[]') + ")"
'(1, 2, 3)'


>>> lst = [1]
>>> strng = str(lst)
>>> "(" + strng.strip('[]') + ")"
'(1)'

Comments

0

Try this:

'({0})'.format(', '.join(str(x) for x in list))

By the way, it's not a good idea to name your own variables list since it clashes with the built-in function. Also string can conflict with the module of the same name.

1 Comment

@Winston I guess your python version is older than 2.7/3.1. The edit fixes it for you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.