Skip to main content
We’ve updated our Terms of Service. A new AI Addendum clarifies how Stack Overflow utilizes AI interactions.
deleted 50 characters in body
Source Link
Sp3000
  • 62.2k
  • 13
  • 117
  • 292

Translating chars in a string

I've seen this situation pop up a few times, so I thought a tip would be good.

Suppose you have a string s and you want to translate some chars of s to other chars (think ROT-13 like ciphers). For a more concrete example, suppose we want to swap just the as and bs in a string, e.g.

"abacus" -> "babcus"

The naïve way to do this would be:

lambda s:s.replace('a','T').replace('b','a').replace('T','b')

Note how we need to introduce a temporary 'T' to get the swapping right.

With eval, we can shorten this a bit:

lambda s:eval("s"+".replace('%s','%s')"*3%tuple("aTbaTb"))

For this particular example, iterating char-by-char gives a slightly better solution (feel free to try it!). But even so, the winner is str.translate, which takes a dictionary of from: to code points:

# Note: 97 is 'a' and 98 is 'b'
lambda s:s.translate({97:98,98:97})

In Python 2 this only works for Unicode strings, so unfortunately the code here is slightly longer:

lambda s:(u''+s).translate({97:98,98:97})

Some important points which make str.translate so useful are:

  • It's easily extendable.

    It's easily extendable.
  • Any char not specified is untouched by default, e.g. the "cus" in "abacus" above.

    Any char not specified is untouched by default, e.g. the "cus" in "abacus" above.
  • The to part of the dictionary can actually be a (Unicode) string or None as well.

    • For the former case, {97:"XYZ"} (u"XYZ" in Python 2) would turn abacus -> XYZbXYZcus.
    • For the latter case, mapping to None drops the char, so {97:None} gives abacus -> bcus.
    The to part of the dictionary can actually be a (Unicode) string as well, e.g. {97:"XYZ"} (u"XYZ" in Python 2) would turn abacus -> XYZbXYZcus. It can also be None, but that doesn't save any bytes compared to "" or u"".

Translating chars in a string

I've seen this situation pop up a few times, so I thought a tip would be good.

Suppose you have a string s and you want to translate some chars of s to other chars (think ROT-13 like ciphers). For a more concrete example, suppose we want to swap just the as and bs in a string, e.g.

"abacus" -> "babcus"

The naïve way to do this would be:

lambda s:s.replace('a','T').replace('b','a').replace('T','b')

Note how we need to introduce a temporary 'T' to get the swapping right.

With eval, we can shorten this a bit:

lambda s:eval("s"+".replace('%s','%s')"*3%tuple("aTbaTb"))

For this particular example, iterating char-by-char gives a slightly better solution (feel free to try it!). But even so, the winner is str.translate, which takes a dictionary of from: to code points:

# Note: 97 is 'a' and 98 is 'b'
lambda s:s.translate({97:98,98:97})

In Python 2 this only works for Unicode strings, so unfortunately the code here is slightly longer:

lambda s:(u''+s).translate({97:98,98:97})

Some important points which make str.translate so useful are:

  • It's easily extendable.

  • Any char not specified is untouched by default, e.g. the "cus" in "abacus" above.

  • The to part of the dictionary can actually be a (Unicode) string or None as well.

    • For the former case, {97:"XYZ"} (u"XYZ" in Python 2) would turn abacus -> XYZbXYZcus.
    • For the latter case, mapping to None drops the char, so {97:None} gives abacus -> bcus.

Translating chars in a string

I've seen this situation pop up a few times, so I thought a tip would be good.

Suppose you have a string s and you want to translate some chars of s to other chars (think ROT-13 like ciphers). For a more concrete example, suppose we want to swap just the as and bs in a string, e.g.

"abacus" -> "babcus"

The naïve way to do this would be:

lambda s:s.replace('a','T').replace('b','a').replace('T','b')

Note how we need to introduce a temporary 'T' to get the swapping right.

With eval, we can shorten this a bit:

lambda s:eval("s"+".replace('%s','%s')"*3%tuple("aTbaTb"))

For this particular example, iterating char-by-char gives a slightly better solution (feel free to try it!). But even so, the winner is str.translate, which takes a dictionary of from: to code points:

# Note: 97 is 'a' and 98 is 'b'
lambda s:s.translate({97:98,98:97})

In Python 2 this only works for Unicode strings, so unfortunately the code here is slightly longer:

lambda s:(u''+s).translate({97:98,98:97})

Some important points which make str.translate so useful are:

  • It's easily extendable.
  • Any char not specified is untouched by default, e.g. the "cus" in "abacus" above.
  • The to part of the dictionary can actually be a (Unicode) string as well, e.g. {97:"XYZ"} (u"XYZ" in Python 2) would turn abacus -> XYZbXYZcus. It can also be None, but that doesn't save any bytes compared to "" or u"".
deleted 4 characters in body
Source Link
Sp3000
  • 62.2k
  • 13
  • 117
  • 292

Translating chars in a string

I've seen this situation pop up a few times, so I thought a tip would be good.

Suppose you have a string s and you want to translate some chars of s to other chars (think ROT-13 like ciphers). For a more concrete example, suppose we want to swap just the as and bs in a string, e.g.

"abacus" -> "babcus"

The naïve way to do this would be:

lambda s:s.replace('a','T').replace('b','a').replace('T','b')

Note how we need to introduce a temporary 'T' to get the swapping right.

With eval, we can shorten this a bit:

lambda s:eval("s"+".replace('%s','%s')"*3%tuple("aTbaTb"))

For this particular example, iterating char-by-char gives a slightly better solution (feel free to try it!). But even so, the winner is str.translate, which takes a dictionary of from: to code points:

# Note: 97 is 'a' and 98 is 'b'
lambda s:s.translate({97:98,98:97})

In Python 2 this only works for Unicode strings, so unfortunately the code here is slightly longer:

lambda s:(u''+s).translate({97:98,98:97})

Some important points which make str.translate so useful are:

  • It's easily extendable, and.

  • Any char not specified is untouched by default, e.g. the "cus" in "abacus" above.

  • The to part of the dictionary can actually be a (Unicode) string or None as well.

    • For the former case, {97:"XYZ"} (u"XYZ" in Python 2) would turn abacus -> XYZbXYZcus.
    • For the latter case, mapping to None drops the char, so {97:None} gives abacus -> bcus.

Translating chars in a string

I've seen this situation pop up a few times, so I thought a tip would be good.

Suppose you have a string s and you want to translate some chars of s to other chars (think ROT-13 like ciphers). For a more concrete example, suppose we want to swap just the as and bs in a string, e.g.

"abacus" -> "babcus"

The naïve way to do this would be:

lambda s:s.replace('a','T').replace('b','a').replace('T','b')

Note how we need to introduce a temporary 'T' to get the swapping right.

With eval, we can shorten this a bit:

lambda s:eval("s"+".replace('%s','%s')"*3%tuple("aTbaTb"))

For this particular example, iterating char-by-char gives a slightly better solution (feel free to try it!). But even so, the winner is str.translate, which takes a dictionary of from: to code points:

# Note: 97 is 'a' and 98 is 'b'
lambda s:s.translate({97:98,98:97})

In Python 2 this only works for Unicode strings, so unfortunately the code here is slightly longer:

lambda s:(u''+s).translate({97:98,98:97})

Some important points which make str.translate so useful are:

  • It's easily extendable, and

  • Any char not specified is untouched by default, e.g. the "cus" in "abacus" above.

  • The to part of the dictionary can actually be a (Unicode) string or None as well.

    • For the former case, {97:"XYZ"} (u"XYZ" in Python 2) would turn abacus -> XYZbXYZcus.
    • For the latter case, mapping to None drops the char, so {97:None} gives abacus -> bcus.

Translating chars in a string

I've seen this situation pop up a few times, so I thought a tip would be good.

Suppose you have a string s and you want to translate some chars of s to other chars (think ROT-13 like ciphers). For a more concrete example, suppose we want to swap just the as and bs in a string, e.g.

"abacus" -> "babcus"

The naïve way to do this would be:

lambda s:s.replace('a','T').replace('b','a').replace('T','b')

Note how we need to introduce a temporary 'T' to get the swapping right.

With eval, we can shorten this a bit:

lambda s:eval("s"+".replace('%s','%s')"*3%tuple("aTbaTb"))

For this particular example, iterating char-by-char gives a slightly better solution (feel free to try it!). But even so, the winner is str.translate, which takes a dictionary of from: to code points:

# Note: 97 is 'a' and 98 is 'b'
lambda s:s.translate({97:98,98:97})

In Python 2 this only works for Unicode strings, so unfortunately the code here is slightly longer:

lambda s:(u''+s).translate({97:98,98:97})

Some important points which make str.translate so useful are:

  • It's easily extendable.

  • Any char not specified is untouched by default, e.g. the "cus" in "abacus" above.

  • The to part of the dictionary can actually be a (Unicode) string or None as well.

    • For the former case, {97:"XYZ"} (u"XYZ" in Python 2) would turn abacus -> XYZbXYZcus.
    • For the latter case, mapping to None drops the char, so {97:None} gives abacus -> bcus.
added 288 characters in body
Source Link
Sp3000
  • 62.2k
  • 13
  • 117
  • 292

Translating chars in a string

I've seen this situation pop up a few times, so I thought a tip would be good.

Suppose you have a string s and you want to translate some chars of s to other chars (think ROT-13 like ciphers). For a more concrete example, suppose we want to swap just the as and bs in a string, e.g.

"abacus" -> "babcus"

The naïve way to do this would be:

lambda s:s.replace('a','T').replace('b','a').replace('T','b')

Note how we need to introduce a temporary 'T' to get the swapping right.

With eval, we can shorten this a bit:

lambda s:eval("s"+".replace('%s','%s')"*3%tuple("aTbaTb"))

For this particular example, iterating char-by-char gives a slightly better solution (feel free to try it!). But even so, the winner is str.translate, which takes a dictionary of from: to code points:

# Note: 97 is 'a' and 98 is 'b'
lambda s:s.translate({97:98,98:97})

In Python 2 this only works for Unicode strings, so unfortunately the code here is slightly longer:

lambda s:(u''+s).translate({97:98,98:97})

TwoSome important points which make str.translate so useful are:

  • It's easily extendable, and

    It's easily extendable, and

  • Any char not specified is untouched by default, e.g. the "cus" in "abacus" above.

    Any char not specified is untouched by default, e.g. the "cus" in "abacus" above.

  • The to part of the dictionary can actually be a (Unicode) string or None as well.

    • For the former case, {97:"XYZ"} (u"XYZ" in Python 2) would turn abacus -> XYZbXYZcus.
    • For the latter case, mapping to None drops the char, so {97:None} gives abacus -> bcus.

Translating chars in a string

I've seen this situation pop up a few times, so I thought a tip would be good.

Suppose you have a string s and you want to translate some chars of s to other chars (think ROT-13 like ciphers). For a more concrete example, suppose we want to swap just the as and bs in a string, e.g.

"abacus" -> "babcus"

The naïve way to do this would be:

lambda s:s.replace('a','T').replace('b','a').replace('T','b')

Note how we need to introduce a temporary 'T' to get the swapping right.

With eval, we can shorten this a bit:

lambda s:eval("s"+".replace('%s','%s')"*3%tuple("aTbaTb"))

For this particular example, iterating char-by-char gives a slightly better solution (feel free to try it!). But even so, the winner is str.translate, which takes a dictionary of from: to code points:

# Note: 97 is 'a' and 98 is 'b'
lambda s:s.translate({97:98,98:97})

In Python 2 this only works for Unicode strings, so unfortunately the code here is slightly longer:

lambda s:(u''+s).translate({97:98,98:97})

Two important points which make str.translate so useful are:

  • It's easily extendable, and
  • Any char not specified is untouched by default, e.g. the "cus" in "abacus" above.

Translating chars in a string

I've seen this situation pop up a few times, so I thought a tip would be good.

Suppose you have a string s and you want to translate some chars of s to other chars (think ROT-13 like ciphers). For a more concrete example, suppose we want to swap just the as and bs in a string, e.g.

"abacus" -> "babcus"

The naïve way to do this would be:

lambda s:s.replace('a','T').replace('b','a').replace('T','b')

Note how we need to introduce a temporary 'T' to get the swapping right.

With eval, we can shorten this a bit:

lambda s:eval("s"+".replace('%s','%s')"*3%tuple("aTbaTb"))

For this particular example, iterating char-by-char gives a slightly better solution (feel free to try it!). But even so, the winner is str.translate, which takes a dictionary of from: to code points:

# Note: 97 is 'a' and 98 is 'b'
lambda s:s.translate({97:98,98:97})

In Python 2 this only works for Unicode strings, so unfortunately the code here is slightly longer:

lambda s:(u''+s).translate({97:98,98:97})

Some important points which make str.translate so useful are:

  • It's easily extendable, and

  • Any char not specified is untouched by default, e.g. the "cus" in "abacus" above.

  • The to part of the dictionary can actually be a (Unicode) string or None as well.

    • For the former case, {97:"XYZ"} (u"XYZ" in Python 2) would turn abacus -> XYZbXYZcus.
    • For the latter case, mapping to None drops the char, so {97:None} gives abacus -> bcus.
Source Link
Sp3000
  • 62.2k
  • 13
  • 117
  • 292
Loading