0
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?

3
  • 2
    What to do if you have a 9? Commented Mar 19, 2014 at 21:56
  • oooh good question, it should go to 0 I think Commented Mar 19, 2014 at 21:56
  • @Ffisegydd: well, since the OP first turned the whole string into a list of individual characters, lets assume SX11293, as map() would apply add to each individual element of that list. Commented Mar 19, 2014 at 22:05

3 Answers 3

3

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.

Sign up to request clarification or add additional context in comments.

1 Comment

I had almost the same solution, but too slow again. Only difference is that I prefered lambda (increment = lambda x: str((int(x) + 1) % 10) ), which makes comprehension more readable: print ''.join(increment(char) if char.isdigit() else char for char in samples)
1

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)

Comments

0
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'

Comments

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.