Hassan Baig
Hassan Baig

Reputation: 15804

String manipulation in nested for loops

Using Python 2.7, imagine I have two variables:

encoded_username = 'bender_in_soup_1234'
code = '000204071012'

The string in code actually specifies the position of upper case characters in encoded_username. I.e. 00 implies the first character is upper case. 02 implies the third character is upper case. 04 implies the fifth character is upper case. And so on. It can possibly go to 99 (usernames are not longer than 100 characters).

The fully decoded username is:

decoded_username = 'BeNdEr_In_SoUp_1234'

What's the most efficient way (in Python 2.7) to decode the encoded_username using the code provided?


I'm trying:

upper_case_positions = [code[i:i+2] for i in range(0,len(code),2)]
for position in upper_case_positions:
    encoded_username[position] = encoded_username[int(position)].upper()
return encoded_uname

But this simply gives me 'str' object does not support item assignment.

Moreover, I'm to parse through multiple usernames while decoding them, i.e. the code above is going to be nested inside a for loop. Having for loops within for loops makes me feel there could have been a more efficient solution. What do you folks suggest? I'm highly intrigued.

Upvotes: 0

Views: 120

Answers (3)

rapdum
rapdum

Reputation: 333

String are immutable Why are Python strings immutable? Best practices for using them

You can use regexp to split in chunk https://stackoverflow.com/a/25430739/123808

You can transform in list ( which is mutable) and rebuild your string once you mutation is done

import re

encoded_username = 'bender_in_soup_1234'
code = '000204071012'

encoded_username_list = list ( encoded_username )

upper_case_positions = [int(pos) for pos in re.findall('.{2}', code)]

for position in upper_case_positions:
    encoded_username_list[position] = encoded_username[position].upper()

print "".join(encoded_username_list)

BeNdEr_In_SoUp_1234

Upvotes: 1

Netwave
Netwave

Reputation: 42678

Here you have an aproach using ord and chr:

encoded_username = 'bender_in_soup_1234'
code = '000204071012'


def upperText(s, pos):
    gap = ord("a") - ord("A")
    upper_case_positions = [int(pos[i:i + 2]) for i in xrange(0, len(pos), 2)]
    txt = map(ord, s)
    for i in upper_case_positions:
        txt[i] -= gap
    return "".join(map(chr, txt))

print upperText(encoded_username, code)
BeNdEr_In_SoUp_1234

Upvotes: 1

asongtoruin
asongtoruin

Reputation: 10359

How about the following:

encoded_username = 'bender_in_soup_1234'
code = '000204071012'

upper_case_positions = [int(code[i:i+2]) for i in range(0, len(code), 2)]

decoded_username = ''.join(let.upper() if pos in upper_case_positions else let 
                           for pos, let in enumerate(encoded_username))
print decoded_username

Firstly, you need to wrap your upper_case_positions as integers to ensure they are usable as positions. We enumerate the word to return each character and its relevant position, and change the case where required. Joining using an empty string gives us our output username. This prints, as expected, 'BeNdEr_In_SoUp_1234'

Upvotes: 2

Related Questions