Python Forum

Full Version: ''.join and start:stop:step notation for lists
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hello everyone,

I am very new to Python. I have only started recently learning the language on my own and as a first programming language. It is a lot of fun, though can also be very frustrating.

I am following the book called Head First Python, 2nd edition.
For those unfamiliar, the book has an example called "Don't panic!" where that phrase gets turned into a list, and then gets transformed into "on tap" before being put back together and printed as a string. After some additional explanation on lists and using slices, the example is given again but you have to use different methods.

To start from the beginning, the first example basically makes you write the following code:
phrase = "Don't panic!"
plist = list(phrase)
print(phrase)
print(plist)

for i in range(4):
    plist.pop()
plist.pop(0)
plist.remove("'")
plist.extend([plist.pop(),plist.pop()])
plist.insert(2,plist.pop(3))

new_phrase =  ''.join(plist)
print(plist)
print(new_phrase)
Output:
Don't panic! ['D', 'o', 'n', "'", 't', ' ', 'p', 'a', 'n', 'i', 'c', '!'] ['o', 'n', ' ', 't', 'a', 'p'] on tap
Afterwards there is explanation on using list slices and the assignment is given again, and you have to try to only use the slices. I wasn't able to not use the previous lines at all, and this was what I wrote initially, which generates the same output as above:

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

plist.remove("'")
plist.insert(6,plist.pop(3))
print(plist)
new_phrase = ''.join(plist[1:4])+''.join(plist[-5:-8:-1])

print(plist)
print(new_phrase)
When looking at the answer the book gave me, they had written the following:

phrase = "Don't panic!"
plist = list(phrase)
new_phrase = ''.join(plist[1:3])
new_phrase = new_phrase + ''.join([plist[5],plist[4],plist[7],plist[6]])
print(new_phrase)
This made me think it was possible to further simplify my own code, specifically the ''.join line.
I noted the code as follows:
phrase = "Don't panic!"
plist = list(phrase)
print(phrase)
print(plist)

plist.remove("'")
plist.insert(6,plist.pop(3))
print(plist)
new_phrase = ''.join([plist[1:4],plist[-5:-8:-1]])
print(plist)
print(new_phrase)
Unfortunately, this does not work as I had expected it to and the interpreter gives me the following error:
Error:
Traceback (most recent call last): File "D:\SelfTraining\Python\HeadFirst\panic2.py", line 47, in <module> new_phrase = ''.join([plist[1:4],plist[-5:-8:-1]]) TypeError: sequence item 0: expected str instance, list found
In order to try and get rid of the error, I have tried noting it as:
new_phrase = [''.join([plist[1:4],plist[-5:-8:-1]])]
new_phrase = ''.join(str([plist[1:4],plist[-5:-8:-1])])
new_phrase = ''.join(str([plist[1:4]),str(plist[-5:-8:-1]))])
However, all give an error. Is this simply a ccase of the start:stop:step notation not working within something like ''.join? If so, how can I figure something out like this in the future?

Thanks in advance!
You were close... Try it like this:

phrase = "Don't panic!"
plist = list(phrase)
 
plist.remove("'")
plist.insert(6,plist.pop(3))
new_phrase = ''.join(plist[1:4] + plist[-5:-8:-1])

print(new_phrase)
(Apr-08-2021, 04:29 PM)BashBedlam Wrote: [ -> ]
phrase = "Don't panic!"
plist = list(phrase)
 
plist.remove("'")
plist.insert(6,plist.pop(3))
new_phrase = ''.join(plist[1:4] + plist[-5:-8:-1])

The explanation being (for the benefit of future readers, if nothing else), the str.join() method requires a list of strings (actually, any iterable producing string values) as its only argument.

# If plist is a list created from a string...
plist = list("Don't panic!")    # => ["D", "o", "n", "'", "t", " ", "p", "a", "n", "i", "c", "!"]
plist.remove("'")              # => ["D", "o", "n", "t", " ", "p", "a", "n", "i", "c", "!"]
plist.insert(6, plist.pop(3))  # => ["D", "o", "n", " ", "p", "a", "t", "n", "i", "c", "!"]

# Then a list of two slices...
''.join( [ plist[1:4], plist[-5:-8:-1] ] )
# is equivalent to...
''.join( [ ["o", "n", " "], ["t", "a", "p"] ] )
Hence the exception, because iterating over the list passed to str.join() will produce two values: the slices ["o", "n", " "] and ["t", "a", "p"], and those aren't strings — they're lists. (Slices are always lists, even if the length is 1. plist[1] == "o", but plist[1:2] == ["o"]. Or even if the length is 0: plist[1:1] == [].)

Using the + operator to concatenate the two slices ensures that str.join() is called with a single list containing only string values.

# Because this...
''.join(plist[1:4] + plist[-5:-8:-1])
# is equivalent to...
''.join( ["o", "n", " ", "t", "a", "p"] )
Which is legal input to str.join().