Reputation: 11
I'm very new to Python and am trying to understand how to manipulate strings.
What I want to do is change a string by removing the spaces and alternating the case from upper to lower, IE "This is harder than I thought it would be" to "ThIsIsHaRdErThAnItHoUgHtItWoUlDbE"
I've cobbled together a code to remove the spaces (heavily borrowed from here):
string1 = input("Ask user for something.")
nospace = ""
for a in string1:
if a == " ":
pass
else:
nospace=nospace+a
... but just can't get my head around the caps/lower case part. There are several similar issues on this site and I've tried amending a few of them, with no joy. I realise I need to define a range and iterate through it, but that's where I draw a blank.
for c in nospace[::]:
d = ""
c = nospace[:1].lower()
d = d + c
c = nospace[:1].upper
print d
All I am getting is a column of V's. I'm obviously getting this very wrong. Please can someone advise where? Thanks in advance.
Upvotes: 1
Views: 2489
Reputation: 4644
The following python script converts strings in any case into alternating-case
import io # input output library
def to_alternating_case(istr:str):
strm = io.StringIO()
# iidx..... input index
# ich .... input character
for idx, ich in enumerate(istr):
if (idx % 2) == 0:
print(ich.lower(), end="", file=strm)
else: # index is odd such as 1, 3, 5, 7, 9...
print(ich.upper(), end="", file=strm)
end_result = strm.getvalue()
strm.close() # prevent a memory leak
# input string
istr = "ATTACK THE DRAGON WITH SWORD"
#
end_result = to_alternating_case(istr)
#
print(end_result)
# input string
istr = "ATTACK THE DRAGON WITH SWORD"
# output string
ostr = "aTtAcK ThE DrAgOn wItH SwOrD"
Upvotes: -2
Reputation: 394
So your 2nd loop is where you're breaking it, because the original list isn't being shortened, the c=nospace[:1] grabs the first character of the string and that's the only character that's ever printed. So a solution would be as follows.
string1 = str(input("Ask user for something."))
nospace = ''.join(string1.split(' '))
for i in range(0, len(nospace)):
if i % 2 == 0:
print(nospace[i].upper(), end="")
else:
print(nospace[i].lower(), end="")
Could also replace the if/else statement with a ternary opperator.
for i in range(0, len(nospace)):
print(nospace[i].upper() if (i % 2 == 0) else nospace[i].lower(), end='')
Final way using enumerate as commented about
for i, c in enumerate(nospace):
print(c.upper() if (i % 2 == 0) else c.lower(), end='')
Upvotes: 0
Reputation: 95948
Here is a cutesie way to do this:
>>> s = "This is harder than I thought it would be"
>>> from itertools import cycle
>>> funcs = cycle([str.upper, str.lower])
>>> ''.join(next(funcs)(c) for c in s if c != ' ')
'ThIsIsHaRdErThAnItHoUgHtItWoUlDbE'
>>>
Or, as suggested by Moses in the comments, you can use str.isspace
, which will take care of not just a single space ' '
>>> ''.join(next(funcs)(c) for c in s if not c.isspace())
'ThIsIsHaRdErThAnItHoUgHtItWoUlDbE'
This approach only does a single pass on the string. Although, a two-pass method is likely performant enough.
Now, if you were starting with a nospace
string, the best way is to convert to some mutable type (e.g. a list
) and use slice-assignment notation. It's a little bit inefficient because it builds intermediate data structures, but slicing is fast in Python, so it may be quite performant. You have to ''.join
at the end, to bring it back to a string:
>>> nospace
'ThisisharderthanIthoughtitwouldbe'
>>> nospace = list(nospace)
>>> nospace[0::2] = map(str.upper, nospace[0::2])
>>> nospace[1::2] = map(str.lower, nospace[1::2])
>>> ''.join(nospace)
'ThIsIsHaRdErThAnItHoUgHtItWoUlDbE'
>>>
Upvotes: 2
Reputation: 39013
You're trying to do everything at once. Don't. Break your program into steps.
Upvotes: 0