简体   繁体   中英

Having trouble with whitespace and strings in a function

Prompt

Turn a string into rollercoaster case. The first letter of the sentence is uppercase, the next lowercase, the next uppercase, and so on.

Code

with open('test.txt') as file:
    for line in file:
        words = line.split()
        for word in words:
            chars = list(word)
            for index, char in enumerate(chars):
                if index == 0:
                    print char.upper(),
                elif is_even(index):
                    print char.upper(),
                elif is_odd(index):
                    print char,

Input

Sunshine makes me happy, on a cloudy day

Output

S u N s H i N e M a K e S M e H a P p Y , O n A C l O u D y D a Y

This is my first attempt at this problem. I can't think of any other way to do this other than to iterate by each letter. When I do this though I'm just treating the entire sentence as a string and spewing out characters.

You can uppercase just every second letter with an extended slice, picking every second letter:

>>> sample = 'Sunshine makes me happy, on a cloudy day'
>>> sample[::2].upper()
'SNHN AE EHPY NACOD A'
>>> sample[1::2].lower()
'usiemksm ap,o  luydy'

Now all you need to do is put those together again:

from itertools import izip_longest

result = ''.join([l 
    for pair in izip_longest(sample[::2].upper(), sample[1::2].lower(), fillvalue='') 
    for l in pair])

izip_longest() pairs up the uppercased and lowercased strings again, making sure that if there is an odd number of characters to pad out the series with an empty string.

Demo:

>>> from itertools import izip_longest
>>> ''.join([l 
...     for pair in izip_longest(sample[::2].upper(), sample[1::2].lower(), fillvalue='') 
...     for l in pair])
'SuNsHiNe mAkEs mE HaPpY, oN A ClOuDy dAy'

Note that whitespace isn't ignored here; the m of make is lowercased even though the e at the end of Sunshine is too.

If you need to vary the letters more precisely, you can make use of iteration still:

from itertools import cycle
from operator import methodcaller

methods = cycle((methodcaller('upper'), methodcaller('lower')))
result = ''.join([next(methods)(c) if c.isalpha() else c for c in sample])

Here itertools.cycle() lets us alternate between two operator.methodcaller() objects , which either upper or lowercase the argument passed in. We only advance to the next one (using next() ) when the character is a letter.

Demo:

>>> from itertools import cycle
>>> from operator import methodcaller
>>> methods = cycle((methodcaller('upper'), methodcaller('lower')))
>>> ''.join([next(methods)(c) if c.isalpha() else c for c in sample])
'SuNsHiNe MaKeS mE hApPy, On A cLoUdY dAy'

If it's whitespace giving you trouble, you should use isalpha() to test if a character is a letter or not.

with open('test.txt') as file:
  for line in file:
    newstr = ""
    go_to_upper = True

    for c in line:
      if c.isalpha():
        if go_to_upper:
          newstr += c.upper()
        else:
          newstr += c.lower()
        go_to_upper = not go_to_upper
      else:
        newstr += c

  print newstr

Input: Sunshine makes me happy, on a cloudy day

Output: SuNsHiNe MaKeS mE hApPy, On A cLoUdY dAy

You'll only flip back and forth (using the go_to_upper boolean) when the character in question is a letter of the alphabet. Otherwise, it's outputted normally. Notice that MaKeS starts with a capital letter, though SuNsHiNe ends with a lowercase letter, even with the space in the way.

Also, instead of printing immediately (which gives you the weird spacing) we're putting our characters in a new list, which we'll print out all at once later.

Try this code :

import re
i = 1
with open('test.txt') as file:
    for line in file:
        words = line.split()
        for word in words:
            chars = list(word)
            for index, char in enumerate(chars):
                if re.compile('[a-zA-Z]').search(char):
                    i+=1
                    if i%2 !=0:
                        print char.upper(),
                    else :
                        print char.lower(),

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM