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