Anagha
Anagha

Reputation: 41

String manipulation using list comprehension

I am trying below code and expecting output as, matching string where every even letter is uppercase, and every odd letter is lowercase, however my output is list of all uppercase characters.

def myfunc(*args):
    return ''.join([args[i].upper() if i%2==0 else args[i].lower() for i in range(len(args))])

How can I get expected output ? I tried same list comprehension syntax to test and it works fine. What's wrong with this specific code ?

Upvotes: 2

Views: 448

Answers (3)

hitesh kaushik
hitesh kaushik

Reputation: 110

The above answers are correct but they ask you to modify the current syntax. In general you should try to understand how *args works.
In python, *args in a function definition is used to receive variable number of arguments. Such cases arise when we don't know in advance how many arguments will be passed.
For example :

def myFun(*argv):
    for arg in argv:
        print (arg)
myFun('Hello', 'Welcome', 'to', 'GeeksforGeeks')

Now coming back to your code, you can make it run by selecting the first argument from the args list. See below :

def myfunc(*args):
    return ''.join([args[0][i].upper() if i%2==0 else args[0][i].lower() for i in range(len(args[0]))])
print(myfunc("input"))

Help the community by selecting the best answer for this question.

Upvotes: 1

Carcigenicate
Carcigenicate

Reputation: 45736

The problem is, you're using var-args. That's wrapping the string passed with a list, then you're iterating over that list (which only contains one string). This means your code does work to some extent; its just alternating the case of each whole word instead of each character.

Just get rid of the var-args:

def myfunc(word):
    return ''.join([word[i].upper() if i%2==0 else word[i].lower() for i in range(len(word))])

print(myfunc("hello world"))
# HeLlo WoRlD

I'll just note, there's a few ways this could have been debugged. If you had checked the contents of args, you would have seen that it only contained a single element when one argument was passed, and two when two arguments were passed. If you had passed two arguments in, you would have also noticed that it alternated the case of each word as a whole. That would have likely given you enough hints to figure it out.

Upvotes: 1

Vasilis G.
Vasilis G.

Reputation: 7846

By writing *args in your function declaration, it means that you're iterating over a number of strings and not just one string. For example:

myfunc('hello', 'goodbye')

Your function will iterate over a hello and goodbye, with hello having an index of 0 which is even number and thus converting its characters to uppercase, whereas goodbye has an index of 1 which is odd and thus covnerting its characters to lowercase:

HELLOgoodbye

If you wish to call your function for only one string, you have to remove the * from *args or inserting the string's characters one by one:

myfunc('h','e','l','l','o')

So, the declaration and implementation of your function should look like this:

def myfunc(args):
    return ''.join([args[i].upper() if i%2==0 else args[i].lower() for i in range(len(args))])

Calling myfunc('hello') will return the correct result.

Upvotes: 1

Related Questions