11
index = [0, 2, 5]
s = "I am like stackoverflow-python"
for i in index:
        s = s[i].upper()
print(s)

IndexError: string index out of range

I understand that in the first iteration the string, s, become just the first character, an uppercase "I" in this particular case. But, I have tried to do it without the "s = " , using swapchcase() instead, but it's not working.

Basically, I'm trying to print the s string with the index letters as uppercase using Python 3.X

Ethan Furman
  • 63,992
  • 20
  • 159
  • 237
Hanan
  • 1,169
  • 3
  • 23
  • 40

2 Answers2

21

Strings are immutable in Python, so you need to create a new string object. One way to do it:

indices = set([0, 7, 12, 25])
s = "i like stackoverflow and python"
print("".join(c.upper() if i in indices else c for i, c in enumerate(s)))

printing

I like StackOverflow and Python
Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
7

Here is my solution. It doesn't iterate over every character, but I'm not sure if converting the string to a list and back to a string is any more efficient.

>>> indexes = set((0, 7, 12, 25))
>>> chars = list('i like stackoverflow and python')
>>> for i in indexes:
...     chars[i] = chars[i].upper()
... 
>>> string = ''.join(chars)
>>> string
'I like StackOverflow and Python'
Tyler Crompton
  • 12,284
  • 14
  • 65
  • 94
  • you don't need `set()` in this case. `string = list(..)` is misleading, you could use `chars` (less misleading). – jfs Nov 21 '11 at 21:14
  • True. I actually optimized the solution and converting to a list is no longer needed. Thanks, though. :) – Tyler Crompton Nov 21 '11 at 21:20
  • And yes, using set is unnecessary but what if the OP want to add an index? A set would make sense for this purpose. – Tyler Crompton Nov 21 '11 at 21:23
  • 1. from `MutableString` docstring: *A faster and better solution is to rewrite your program using lists.* 2. `indexes = [0, 2, 5]` ... OP want to add an index ... `indexes.append(1)`. – jfs Nov 21 '11 at 21:34
  • But if an index already exists, you're doubling the work for that index. It just makes sense to use a set. From `set`'s docstring: "Build an unordered collection of unique elements." It doesn't need to be ordered and every index should be unique since it wouldn't make sense to have duplicates. – Tyler Crompton Nov 21 '11 at 21:41
  • Rolled back. I found some benchmarking and this looks to be quickest. – Tyler Crompton Nov 21 '11 at 21:53
  • imagine you use `.swapcase()` instead of `.upper()` then `list()` and `set()` indexes yield different results. btw, `string = ''.join(string)` looks awkward `string = ''.join(chars)` might be better in this case. – jfs Nov 21 '11 at 22:33
  • Why use `swapcase()` when you're specifying the indexes to be capitalized? Why would you add an index a second time to practically remove it? It's semantically incorrect and `set` is the proper data structure. As far as changing, the name of the variable, done. Thanks. :) – Tyler Crompton Nov 22 '11 at 07:25