Another capitalise every odd char of the string solution

前端 未结 2 1979
花落未央
花落未央 2021-01-14 06:12

I just started studying Python and created some kind of task for myself that I\'m struggling to solve...

So, I\'m on chapter on working with strings (accessing strin

相关标签:
2条回答
  • 2021-01-14 06:34

    Your are right to prefer a slicing solution over those in the linked question. (OTOH, that's a slightly different question because it skips spaces). However, your current code is rather inefficient because it recreates the T[::2] and T[1::2] slices on every iteration of the for loop. Also, calling .upper or .lower on single characters is less efficient than calling it on larger strings.

    Here's an efficient way to do this using slicing.

    T = 'somesampletexthere'
    R = [''] * len(T)
    R[::2], R[1::2] = T[::2].upper(), T[1::2].lower()
    R = ''.join(R)
    print(R)
    

    output

    SoMeSaMpLeTeXtHeRe
    

    It may help you understand what's going on if we split up those assignments to R.

    T = 'somesampletexthere'
    R = [''] * len(T)
    R[::2] = T[::2].upper()
    print(R)
    R[1::2] = T[1::2].lower()
    print(R)
    R = ''.join(R)
    print(R)
    

    output

    ['S', '', 'M', '', 'S', '', 'M', '', 'L', '', 'T', '', 'X', '', 'H', '', 'R', '']
    ['S', 'o', 'M', 'e', 'S', 'a', 'M', 'p', 'L', 'e', 'T', 'e', 'X', 't', 'H', 'e', 'R', 'e']
    SoMeSaMpLeTeXtHeRe
    

    We can do those slice assignments in either order:

    T = 'somesampletexthere'
    R = [''] * len(T)
    R[1::2] = T[1::2].lower()
    print(R)
    R[::2] = T[::2].upper()
    print(R)
    R = ''.join(R)
    print(R)
    

    output

    ['', 'o', '', 'e', '', 'a', '', 'p', '', 'e', '', 'e', '', 't', '', 'e', '', 'e']
    ['S', 'o', 'M', 'e', 'S', 'a', 'M', 'p', 'L', 'e', 'T', 'e', 'X', 't', 'H', 'e', 'R', 'e']
    SoMeSaMpLeTeXtHeRe
    

    Just for fun, here's an alternative strategy that zips the upper & lower case strings together. We use izip_longest (or zip_longest in Python 3) so we can handle strings that have an odd length.

    from itertools import izip_longest
    
    T = 'somesampletexthere'
    R = ''.join([c for t in izip_longest(T[::2].upper(), T[1::2].lower(), fillvalue='') for c in t])
    print(R)
    

    Although this version does it in one line I prefer my first version: I find it more readable, and it's probably a little faster.

    0 讨论(0)
  • 2021-01-14 06:45

    You could just use enumerate and test for odd and even indices using a ternary operator. Then use join to join the string:

    >>> T = 'somesampletexthere'
    >>> ''.join(x.upper() if i%2 else x.lower() for i, x in enumerate(T))
    'sOmEsAmPlEtExThErE'
    

    You could handle whitespaces by using an external counter object provided by itertools.count:

    >>> from itertools import count
    >>> c = count()
    >>> T = 'some sample text here'
    >>> ''.join(x if x.isspace() else (x.upper() if next(c)%2 else x.lower()) for x in T)
    'sOmE sAmPlE tExT hErE'
    
    0 讨论(0)
提交回复
热议问题