user2572526
user2572526

Reputation: 1279

Python wrong result joining lists

I'm studying Python 3 and I'm blocked on an very simple exercise:
Having the string "Don't panic" convert it to "on tap" using the square brackets notation.

This is my code:

phrase = "Don't panic!"
plist = list(phrase)
new_phrase = ''.join(plist[1:3]).join(plist[5:3:-1]).join(plist[-5:-7:-1])
print(new_phrase)

I expect to have in output the string "on tap"

''.join(plist[1:3])     //"on"
.join(plist[5:3:-1])    //" t"
.join(plist[-5:-7:-1])  //"ap"

but I have "a ontp" instead.
Why?!?

NOTE: I know that there are other ways to solve this exercise, and I'm able to solve it in a different manner. I'm not looking for an alternative solution, I'm trying to understand what is wrong with the code that I wrote above.

Upvotes: 2

Views: 306

Answers (5)

Patrick Artner
Patrick Artner

Reputation: 51643

Whatever comes before the .join() is interspaced in every element of what ever is inside the parenthesis:

'---'.join( "..." )  ==>  .---.---. 

You are chaining calls of join - so every result is interspaced into the following join part:

phrase = "Don't panic!"
plist = list(phrase)

np1 = ''.join(plist[1:3])          # with itermediate results, see output
np2 = np1.join(plist[5:3:-1])      #   the slice is "t ", it puts 'on' between " " and "t"
np3 = np2.join(plist[-5:-7:-1])    #   the slice is "ap", it puts " ont" between
                                   #   'a' and 'p' 

print(np1,np2,np3 )   # ('on', ' ont', 'a ontp')

Alternate solution:

print( phrase[1:3]+phrase[5:3:-1]+phrase[7:5:-1] )

Gives:

on tap

Upvotes: 1

Lorenzo Fiamingo
Lorenzo Fiamingo

Reputation: 4069

If you take for example

something.join(somethingElse)

something will be the interspacing for somethingElse. So in your code every time you use a join you are using what comes first as the interspacing for what are you joining. That's it.

Upvotes: 0

Sam
Sam

Reputation: 88

It would be much more efficient if you created string slices

phrase = "Don't panic!"
new_pharse = phrase[1:3] + phrase[5:3:-1] + phrase[-5:-7:-1]
print(new_pharse)

Upvotes: 0

Filip Młynarski
Filip Młynarski

Reputation: 3612

Simply add your elements instead of trying to join its content by their previous element.

phrase = "Don't panic!"
plist = list(phrase)
new_phrase = ''.join(plist[1:3]) + ''.join(plist[5:3:-1]) + ''.join(plist[-5:-7:-1])
print(new_phrase) # -> on tap

Your code didn't work because you were joining [" ", "t"] and ["a", "p"] by their previous elements:

                         "a ontp"
                           | - joined
           _________________________________
           |                                |
         " ont"                             |
           | - joined                       |
 _______________________                    |
 |                      |                   |
"on"                [" ", "t"]          ["a", "p"]
 |                      |                   |
''.join(plist[1:3]).join(plist[5:3:-1]).join(plist[-5:-7:-1])

Upvotes: 3

Paritosh Singh
Paritosh Singh

Reputation: 6246

Each successive join is utilizing what is in front to...well..join the elements with. This is why your code gives that result. as a recommendation, print the intermediates.

phrase = "Don't panic!"
plist = list(phrase)
new_phrase = ''.join(plist[1:3]).join(plist[5:3:-1]).join(plist[-5:-7:-1])

print(''.join(plist[1:3])) #'on'
print(plist[5:3:-1]) #[' ','t']
print(''.join(plist[1:3]).join(plist[5:3:-1])) #' ont'
print(plist[-5:-7:-1]) #['a','p']
print(new_phrase) #a ontp

Upvotes: 1

Related Questions