1

I am new in programming...My code is very simple. Let's say my number is '123' then i want to get 'abc' .please check where i am wrong

def number2char(number):
    search_array = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]
    replace_array = ["a", "b", "c", "d", "d", "e", "f", "g", "h", "i"]
    num_2_char = number.replace(search_array, replace_array);
    return num_2_char;  

I am getting an error here like this

num_2_char = number.replace(search_array, replace_array); TypeError: expected a character buffer object

Please help me...

3
  • 1
    You can't just guess at what you want a method to do. It does what it was documented to do. For str.replace, what it does is replace one substring with another substring. Commented Jun 23, 2018 at 8:14
  • Thanks for editing...please anyone help me! Commented Jun 23, 2018 at 8:15
  • Is it intentional that you have "d" twice in a row? Commented Jun 23, 2018 at 8:25

3 Answers 3

2

The problem is that str.replace replaces one substring with a replacement substring. That's what the error means: it wants a substring, and you gave it a list of separate characters.


You could loop over the replacement pairs, calling replace for each one:

>>> s = '123'
>>> for search, replace in zip(search_array, replace_array):
...     s = s.replace(search, replace)
>>> s
'abc'

Or you could just use str.translate, which actually does do what you want, although it requires a bit of setup:

>>> search_array = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]
>>> replace_array = ["a", "b", "c", "d", "d", "e", "f", "g", "h", "i"]
>>> trans = str.maketrans(dict(zip(search_array, replace_array)))
>>> '123'.translate(trans)
'abc'

Or, alternatively, and probably more readable:

>>> search = "1234567890"
>>> replace = "abcddefghi"
>>> trans = str.maketrans(search, replace)
>>> '123'.translate(trans)
'abc'

By the way, if it isn't intentional that you specified d twice in a row, it might be clearer (and harder to make that typo!) to specify the letters like this:

>>> replace = string.ascii_lowercase[:10]
Sign up to request clarification or add additional context in comments.

Comments

1

You can use a dictionary instead. There's a few steps here:

  1. We want to map every number to a character, so we can create a dictionary with the input characters as keys and the output characters as values.
  2. You can't iterate a numerical input, so we have to convert it to a string to access each character in turn. In your example the value is already a string ('123') but there's no reason you can't make the function accept both numerical and string inputs.
  3. The replacement is done in a list comprehension, which naturally returns a list. So you need to call join() to join all of the characters back together into a single string.

One approach is as follows:

def number2char(number):
    search_array = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]
    replace_array = ["a", "b", "c", "d", "d", "e", "f", "g", "h", "i"]
    replace_dict = dict(zip(search_array, replace_array))
    num_2_char = ''.join([replace_dict.get(char, '_') 
                          for char in str(number)])
    return num_2_char

a = number2char(123)

In this case I've used replace_dict.get(str(item), '_') so that the code doesn't crash if someone gives an input that isn't in the replace_dict; instead they just get back underscores. There's probably better ways to handle that, but it's safer than just trying to access the dictionary as replace_dict[item].

16 Comments

Great explanation and very helpful . Thank you very much @roganjosh
What is point 2 about? The OP says the input is 123', which is a string. Plus, if it weren't a string, he wouldn't get the TypeError he got, he'd get an AttributeError.
@abarnert ah, that's a fair enough observation. You're right, I missed that the input was already a string, but I was already working on an explanation for dict.get(). I guess that point is a bit redundant but I'm not sure it affects the flow of the explanation to be removed?
I think it confuses things, especially for a novice who's going to start trying to figure out why '123' isn't a string.
Also, I think dict.get(item, item) might be more useful than dict.get(item, '_')… but that's really up to what the OP wants to happen in that case. (He might actually want an error, because that's a "this should never happen" case, for all I know.)
|
-1
def number2char(number):
    search_array = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"]
    replace_array = ["a", "b", "c", "d", "d", "e", "f", "g", "h", "i"]
    num_2_char=''
    for i in number:
        num_2_char +=  replace_array[search_array.index(i)]
    return num_2_char;

1 Comment

This really isn't a good solution. Almost any time you find yourself calling index on a list, it's a sign that you're using either the wrong data structure or the wrong algorithm. Here, you could just use a dict, instead of linearly searching through every character every time—it would be simpler, and clearer in meaning, and even more efficient (not that it's going to matter here). But at that point, you've just got roganjosh's answer.

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.