On 2/20/2021 12:02 PM, jak wrote:
Il 20/02/2021 15:40, C W ha scritto:
Hello everyone,

I'm curious if there is a way take number and back each digit by 3 ?

2342 becomes 9019
8475 becomes 5142
5873 becomes 2540

The tricky part is that 2 becomes 9, not -1.

Here's my toy example and what I attempted,
test_series = pd.Series(list(['2342', '8475', '5873']))
test_series
0    2342
1    8475
2    5873
dtype: object

test_series.str.split('')
[, 2, 3, 4, 2, ]
[, 8, 4, 7, 5, ]
[, 5, 8, 7, 3, ]
dtype: object

What a good approach to this? Is there a method or function that should be
handling this?

MRAB gave the proper answer -- str.translate (and str.maketrans.

 >>> num='0123456789'
 >>> n=8475
 >>> sn = ''
 >>> for x in str(n):
       sn += num[(int(x) - 3) % 10]

>  >>> int(sn)
> 5142

This works, but suggesting to beginners that they build strings with += is an O(n*n) trap. Try it with a string of millions of digits. Much better to use str.join

''.join(num[(int(c)-3) % 10] for c in '9876543210')
#'6543210987'

Even better, improve your string lookup idea to avoid the arithmetic.

lookup1 = '7890123456'
''.join(lookup1[int(c)] for c in '9876543210')
#'6543210987'

To avoid the int call, make a lookup dictionary

lookup2 = {a:b for a, b in zip('0123456789', '7890123456')}
''.join(lookup2[c] for c in '9876543210')
#'6543210987'

To run faster, use the str methods maketrans and translate to do the same thing.

lookup3 = str.maketrans('0123456789', '7890123456')
'9876543210'.translate(lookup3)
#'6543210987'

Note that "built-in function" str.maketrans is in effect a static method of the str class and is not an instance method. '0123456789'.maketrans('7890123456') does not work. The reason is that the first argument can be a dict instead of a string. Indeed, the dict could be the char-char mapping above created with the dict comprehension.

Also, the resulting dict maps unicode ordinals to unicode ordinals, rather than chars to chars, because at the C level, a string *is* a sequence of unsigned ints with a PyObject wrapper.

>>> lookup3
{48: 55, 49: 56, 50: 57, 51: 48, 52: 49, 53: 50, 54: 51, 55: 52, 56: 53, 57: 54}

In Python, this is
{ord(a):ord(b) for a, b in zip('0123456789', '7890123456')}

--
Terry Jan Reedy


--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to