I did it in the following way:
why we will use For statement in this problem? please explain me. thanks
I am not sure why my solution is not accepted in the module. When the code below executes, the output is correct in the terminal but I receive an error " Value for author_last_names
did not match the expected value."
Hi Dustinhall,
What do the instruction state? What is the expected output type
suppose to be (ie., None
, string
, list
etc,) ? Try wrapping the code in a function and returning the result:
def solve(names):
author_names = authors.split(',')
author_names = ' '.join(author_names)
author_names = author_names.split(' ')
author_last_names = []
for i in range(1, len(author_names), 2):
author_last_names.append(author_names[i])
return author_last_names
if __name__ == '__main__':
authors = "Audre Lorde,Gabriela Mistral,Jean Toomer,An Qi,Walt Whitman,Shel Silverstein,Carmen Boullosa,Kamala Suraiyya,Langston Hughes,Adrienne Rich,Nikki Giovanni"
print(solve(authors))
Let me know if that works for you.
Hello. So far, this was one of the most enjoyable challenges.
I need some help, seeing that my attempt at a solution was not a âfor loopâ but rather a âlist comprehensionâ.
The problem is that I got stuck with one major issue: What can I add to my list comprehension code (blue box on attached screenshot) so that the end result is the same as the answer provided (orange box).
Thank you.
In your screenshot, author_names
is a list of strings.
I donât quite understand the motivation behind your choice of [::-2]
for the slice in the blue box. But putting that aside for the time being, your code in the blue box is doing:
author_names[i].split(" ")
splits the string on whitespace and creates a list of the words (Since whitespace is the default, so instead of .split(" ")
, you could write it as .split()
if you want).
author_names[i].split(" ")[::-2]
slices the above list and saves the result in a list.
If instead of a list, we were slicing a string, the result would also be a string e.g.
print("abcdefghij"[::-2])
# Output: "jhfdb"
print(["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"][::-2])
# Output: ['j', 'h', 'f', 'd', 'b']
This is why in your blue box output, the last name strings are in lists e.g.
"Audre Lorde".split(" ")
# Split method creates a list
# ["Audre", "Lorde"]
"Audre Lorde".split(" ")[::-2]
# Slicing a list returns a list
# ["Lorde"]
If instead of slicing, you use the element index to select the last word of the split words, then you will get same output as orange box:
# You wrote:
author_last_names = (author_names[i].split(" ")[::-2] for i in range(0, len(author_names)))
# Changing from slicing a list to indexing an element of the list
author_last_names = (author_names[i].split(" ")[-1] for i in range(0, len(author_names)))
print(list(author_last_names)) # Same output as orange box
A few more remarks:
-
In your blue box code, you are using
i
to loop over the index of theauthor_names
and then you access the name byauthor_names[i]
. Since you arenât doing any re-assigning, you donât really need to keep track of the index. Instead you can loop over the elements directly. -
Also, because you chose to use parentheses
()
instead of square brackets[]
, so in your blue box codeauthor_last_names
actually ends up being a generator object. You then have to convert this object to a list when you want to print it i.e.print(list(author_last_names))
Keeping in view the above observations, you could write the code in blue box as a list comprehension like so:
author_last_names = [name.split()[-1] for name in author_names]
print(author_last_names)
Now author_last_names
is a list instead of a generator object.
Thank you! Very helpful indeed.
Now that I checked for this explanation, it all makes sense.
I solved it by using for loops but itâs ofc not nearly as concise as the provided answer:
author_names = authors.split(â,â)
print(author_names)
author_all_names =
author_last_names =
for n in author_names:
author_all_names.append(n.split())
for n in author_all_names:
author_last_names.append(n[1])
I think the developer of the course should at least give an example of .split() being followed by an index in the introduction. That way it would be less confusing. At least for me I didnât realize I could directly use index after a built in method
I agree with you: in a number of introduction notes, the explanations are not very detailed.
I also receive this code if the answer is correct but doesnât match the âexpected answerâ.
Makes me think that the course organisers only had one solution per challenge, which is strange, given that for most programming challenges, a few possible answers could exist.
Can you share the latest code for your solution? Also, what exact feedback/error message is being shown?
It is probable that your code may not be working as stipulated for certain edge cases. There may also be some test cases which arenât visible to the coders, but are being used by the system to validate the results for different arguments.
In dustindhallâs solution, if the argument is a bit different, then the code doesnât return the expected output.
For Example,
// Works for this
authors = "Audre Lorde,Gabriela Mistral,Jean Toomer,An Qi,Walt Whitman"
...
print(author_last_names)
// ['Lorde', 'Mistral', 'Toomer', 'Qi', 'Whitman']
// Doesn't work correctly for this
authors = "Audre Lorde,Gabriela Mistral,Jean Nathan Toomer,An Qi,Walt Whitman"
...
print(author_last_names)
// ['Lorde', 'Mistral', 'Nathan', 'An', 'Walt']
// The middle name of one of the authors breaks the logic of dustindhall's solution
// which assumes that every second word is the last name.
My first time actually using the forum to ask a question, hope Iâm even in the right place. So⌠I got the question right, but I feel like there must be a way to do both functions in one list comprehension. If there is anyone able to explain to me how? (I did try, couldnât figure it out) Otherwise if there isnât a way also just letting me know that would be helpful lol.
authors = âAudre Lorde,Gabriela Mistral,Jean Toomer,An Qi,Walt Whitman,Shel Silverstein,Carmen Boullosa,Kamala Suraiyya,Langston Hughes,Adrienne Rich,Nikki Giovanniâ
author_names = authors.split(â,â)
print(author_names)
last_names = [i.split() for i in author_names]
author_last_names = [i[-1] for i in last_names]
print(last_names)
print(author_last_names)
One way to do so would be:
authors = "Audre Lorde,Gabriela...,Nikki Giovanni"
author_names = authors.split(',')
author_last_names = [name.split()[-1] for name in author_names]
print(author_last_names)
authors
is a string of names separated by commas.
Splitting the authors
string using comma (as the delimiter for the separation) creates a list of strings. This list is assigned to author_names
.
In the list comprehension, the for loop iterates over each string in the author_names
list and assigns it to the variable name
.
name.split()[-1]
First the split
method splits the string on whitespace and creates another list. Then the index [-1]
allows us to target the last element of the list i.e. the last name.
You could also do:
authors = "Audre Lorde,Gabriela...,Nikki Giovanni"
author_last_names = [name.split()[-1] for name in authors.split(',')]
print(author_last_names)
But, it is probably easier to follow what is going on in the former snippet compared to the latter one-liner.
No those are both great. Iâm a lot further in since I posted that but seeing problems done multiple different ways is a lot of help to perceive the options I have mentally. Thank you for that! The second answer is what I was really looking for/trying to do, couldnât get it through my head why I couldnât make it work in one list comprehension. While I have ya here mind if I ask another question? I am doing " Casual Coded Correspondence: The Project" on jupyter notebook.
And I have been playing around trying to figure out if thereâs a way to only iterate the proper result from this functionâŚ
vishals_encrypted_message3 = 'vhfinmxkl atox kxgwxkxw tee hy maxlx hew vbiaxkl tl hulhexmx. px\'ee atox mh kxteer lmxi ni hnk ztfx by px ptgm mh dxxi hnk fxlltzxl ltyx.'
def caesar_decryption(message, offset):
decrypted_message = ''
for letter in message:
if letter not in alphabet:
decrypted_message += letter
else:
decrypted_message += alphabet[(alphabet.index(letter) + offset) % len(alphabet)]
return decrypted_message
for x in range(len(alphabet)):
print(caesar_decryption(vishals_encrypted_message3, x))
#Originally I tried using the .format() method inside the loop in the function to iterate through, create and return multiple variables so I could use a...
variables being made like variable_attempt{x}.format(x) = 'result from this iteration'
if x in vishals_encrypted_message3:
elif x2 in vishals_encrypted_message3:
Etc...
return variable{x}
where x1 is âtoâ, x2 is âisâ, x3 is âtheâ and so on with common words in all sentences. The return variable{x} being that iteration of the main function loop. I couldnât get it to work though so I guess you cant use .format() like that, does anything come to mind for you or do you see someone I did wrong? I think Iâm probably trying a bit too hard to learn too fast using concepts I donât understand enough yet when I donât need to, but I find that concept a really powerful one if it cant work so if it can id like to know. (Hope I explained that well enough, all my (x)s are just variables for the variables not indicative of what they actually were).
(Iâm still just getting used to the forums btw, sorry thats not formatted well. Only my 3rd post here and only been studying on codecademy like 8-9 days)
Say for example you have a list of just two elements/items:
e.g: my_list = [âaâ, âbâ] using [1] to access the last element/item [1] will work. But in a situation where you have more than two elements/items in a list, that wonât work as [1] will only give you the element/item at the second index.
Using the negative index notation helps us access the elements/items in the list from the right hand side.
So, say will have a list containing 5 elements/items.
e.g: my_list = [âaâ, âbâ, âcâ, âdâ, âeâ] to access the last element/item in the list, you use [-1]
print(my_list[-1])
To access the second to the last element/item you use [-2]
print(my_list[-2]
And so on and so forth.
I hope this was helpful!
You can break it down this way which is easier to understand:
authors = âAudre Lorde,Gabriela Mistral,Jean Toomer,An Qi,Walt Whitman,Shel Silverstein,Carmen Boullosa,Kamala Suraiyya,Langston Hughes,Adrienne Rich,Nikki Giovanniâ
author_names = authors.split(â,â)
author_last_names = [ ]
for name in author_names:
full_name = name.split()
author_last_names.append(full_name[-1])
print(author_last_names)
Thank you for this solution.
I tried what I believe to be the same thing, but Iâm getting a different result.
author_last_names =
for names in author_names:
last_names = names.split()[-1]
author_last_names.append(last_names)
print(author_last_names)
The difference being that I assigned names.split()[-1] to a new variable. And then appended that variable to author_last_names.
This code prints only the very last item on the list. Can anybody explain why, please?
doesnât pop() by default remove the last item(when the parenthesis is empty)? how did it remove the first name?
To preserve code formatting in forum posts, see: [How to] Format code in posts
Indentation is important in Python.
Based on your observation, I suspect your code is:
author_last_names = []
author_names = author_names.split(",")
for names in author_names:
last_names = names.split()[-1]
author_last_names.append(last_names)
print(author_last_names)
Since the append
statement is outside the loop, so it is executed only once. Hence, the output mentioned by you. You should consider making the append
statement a part of the loopâs body by indenting it properly,
for name in author_names:
last_name = name.split()[-1]
author_last_names.append(last_name)