简体   繁体   中英

Python: add 1 to each digit that is an integer

samples = list('SX00182')

def add(x):
    if type(x) == int:
        return x + 1

new_sample = map(add, samples)

result = ''.join(new_sample)

Is there a more efficient way of doing this?

You are dealing with strings here, each character is still a string and type(x) will never be int . You wanted str.isdigit() instead.

Use a list comprehension instead:

new_sample = [x if not x.isdigit() else str((int(x) + 1) % 10) for x in samples]

Here the expression str((int(x) + 1) % 10) casts your character to an integer, adds 1, 'wraps round' to 0 if the result was 10, and turns the whole result into a string again.

You don't need to turn samples into a list even, this works on strings too:

>>> samples = 'SX00182'
>>> [x if not x.isdigit() else str((int(x) + 1) % 10) for x in samples]
['S', 'X', '1', '1', '2', '9', '3']

Complete code:

def increment_digits(string):
    return ''.join([x if not x.isdigit() else str((int(x) + 1) % 10) for x in string])

Demo:

>>> def increment_digits(string):
...     return ''.join([x if not x.isdigit() else str((int(x) + 1) % 10) for x in string])
... 
>>> increment_digits('SX00182')
'SX11293'
>>> increment_digits('SX11293')
'SX22304'

Note that even if you could use a type(x) == int test, you should never use type() that way. First of all, types are best tested with identity ( type(x) is int ), not equality, and you'd use isinstance(x, int) instead to allow for subclasses too.

Generally in Python, "more efficient" means "do less" and "push it down so any loops are happening at a lower level - looping in C rather than in Python".

Since you only have ten, single character mappings (0:1, 1:2, etc.) then there's absolutely no need to check them to see if they are digits, convert them to integers, mathematically calculate on them, modulo the answer to keep it a single digit, build a list, add them to the list, then convert the whole thing back to a string.

Instead, replace them blindly as text, and then, push that down to a C library feature which does the work for you. String.maketrans maps the text characters on the left to the ones on the right, and then string.translate replaces text characters using the translation table.

import string
samples = "SX00182"

translation = string.maketrans('0123456789', '1234567890')

print string.translate(samples, translation)
next_digit = {str(i):str((i+1)%10) for i in range(10)}

def incr(s):
    return ''.join(next_digit.get(ch, ch) for ch in s)

incr("SX001829")   # => 'SX112930'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM