The Palindromes, Python, Problems - python

I am a newbie python coder learning for fun. I am wondering why this program has difficulty outputting the correct output. I believe the problem lies with the very end of the program "if list == inverselist:".
I always get an output telling me the word is a palindrome even when it is not (e.g. tigers)
#Exercise 6 - Ask the user for a string and print out whether this string is a palindrome or not. (A palindrome is a string that reads the same forwards and backwards.)
possiblepalindrome = str(input("Put in the possible palindromic statement here: "))
print(possiblepalindrome)
list=[]
for x in possiblepalindrome: #put each individual string character in a new list as its own element
list.append(x)
print ('this is list', list)
for x in list: #Removes all spaces so multiple word/sentences can be palindrome
if x is ' ':
list.remove(' ')
print('this is with removed spaces' , list)
def reverselist(argument): #This is a function. We put in some list, then the list is reversed, and is spat back out
argument.reverse()
return argument
inverselist = reverselist(list) #We use the reverselist function to make an inverse list of the palindrome
print('this is inverselist',inverselist)
if list == inverselist:
print('Congratulations ', '"', possiblepalindrome, '"', ' is a palindrome!')
else:
print('Unfortunately', '"', possiblepalindrome, '"', 'is not a palindrome.')

list and inverselist have the reference to the same list. You need to clone the list.
Just change the reverselist function
def reverselist(argument): #This is a function. We put in some list, then the list is reversed, and is spat back out
li_copy = []
li_copy.extend(argument)
li_copy.reverse()
return li_copy
Entire code:
possiblepalindrome = str(input("Put in the possible palindromic statement here: "))
print(possiblepalindrome)
list=[]
for x in possiblepalindrome: #put each individual string character in a new list as its own element
list.append(x)
print ('this is list', list)
for x in list: #Removes all spaces so multiple word/sentences can be palindrome
if x is ' ':
list.remove(' ')
print('this is with removed spaces' , list)
def reverselist(argument): #This is a function. We put in some list, then the list is reversed, and is spat back out
li_copy = []
li_copy.extend(argument)
li_copy.reverse()
return li_copy
inverselist = reverselist(list) #We use the reverselist function to make an inverse list of the palindrome
print('this is inverselist',inverselist)
if list == inverselist:
print('Congratulations ', '"', possiblepalindrome, '"', ' is a palindrome!')
else:
print('Unfortunately', '"', possiblepalindrome, '"', 'is not a palindrome.')

You posted far too much code, and didn't bother to test it. reverselist doesn't work the way you expect. It reverses the input list, which is a mutable object.
def reverselist(argument): #This is a function. We put in some list, then the list is reversed, and is spat back out
argument.reverse()
return argument
word = list("Hello, world")
print(word)
inverseword = reverselist(word)
print(word, '\n', inverseword)
Output:
['H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd']
['d', 'l', 'r', 'o', 'w', ' ', ',', 'o', 'l', 'l', 'e', 'H']
['d', 'l', 'r', 'o', 'w', ' ', ',', 'o', 'l', 'l', 'e', 'H']
In short, you reversed the list, and then compared the result to itself.
Notes:
Do not use a pre-defined name as a variable. I changed list to word.
Look up how to reverse a sequence. We expect you to do appropriate research before posting here.
Learn to test code blocks. See this lovely reference for debugging help.
Your function can be simply:
return argument[::-1]

First, naming your list list is tempting but dangerous in Python as you will not be able to call the list() constructor
Basically your code could be reduced like this
possiblepalindrome = str(input("Put in the possible palindromic statement here: "))
print(possiblepalindrome)
normal_list = list(possiblepalindrome.remove(" "))
inverselist= list(reversed(possiblepalindrome))
print('this is inverselist',"".join(inverselist))
if list == inverselist:
print('Congratulations ', '"', possiblepalindrome, '"', ' is a palindrome!')
else:
print('Unfortunately', '"', possiblepalindrome, '"', 'is not a palindrome.')

To check if a string is a palindrome:
v = str(input("Put in the possible palindromic statement here: "))
print (v == (v[::-1]))
Just take the input, compare to the reverse. If those are equal you get a True (so it is a palindrome) otherwise a False.

Related

why does conditional list.insert() in python add additional items to list [duplicate]

This question already has answers here:
Python: Adding element to list while iterating
(12 answers)
Closed 9 months ago.
h = list('camelCase')
for i in range(len(h)):
if h[i].isupper():
h.insert(i,' ')
print(h) returns: ['c', 'a', 'm', 'e', 'l', ' ', ' ', ' ', ' ', 'C', 'a', 's', 'e']
I expected: ['c', 'a', 'm', 'e', 'l', ' ', 'C', 'a', 's', 'e']
since there's only one uppercase letter "C"
Changing the list you are iterating on isn't always a good idea but if you want to apply it on the same list you can use while loop:
h = list('camelCase')
i = 0
while (i < len(h)):
if h[i].isupper():
h.insert(i,' ')
i += 1
i += 1
You need to copy the original list first.
The reason the space letters are added repeatedly is that " " is added in the list h so "C" is taken continuously until the index i reaches the original length of h.
h = list('camelCase')
a = h.copy()
for i in range(len(h)):
if h[i].isupper():
a.insert(i,' ')
print(a)
Your issue is that you are iterating over the range of the list, and when you find a capital letter, you insert the space in that position, which means that the capital letter will be move to the next position, therefore once you find a capital letter it will simply add a space and check that letter again.
Your h[i] right now would print the following:
`c`, `a`, `m`, `e`, `l`, `C`, `C`, `C`, `C`
My recommendation would be to not modify the original list, but do it in a separate one:
h = list('camelCase')
new_text = ''
for i in range(len(h)):
if h[i].isupper():
new_text += ' '
new_text += h[i]

Can you add characters from a string to a list?

I'm wondering if it's possible to take a string e.g. str(input()) and split it into individual chars, then add them to a list. I'm trying to make a simple script (something similar to a hangman game) and at the beginning I wrote this:
x=input('Choose word: ').lower()
letters=[]
letters.append(list(x))
print(letters)
but this code appends the whole list to a list and not individual chars
Edit: this outputs [['o', 'u', 't', 'p', 'u', 't']] meaning that the whole list got appended as one item, but I want this to output ['o', 'u', 't', 'p', 'u', 't'], how do I make it append individual chars and not the whole list
You are simply wrapping the char list in another list.
Try this one-liner instead:
print(list(x))
If you want to remove a character:
letters = list(x)
letters.remove('o')
print(letters)
Use extend instead of append function.
#Extend
x=input('Choose word: ').lower()
letters=[]
letters.extend(list(x))
print(letters)
# ['p', 'y', 't', 'h', 'o', 'n']
And to remove a character from a list while retaining position as blank after removing, use replace while within a list:
y=input("Choose a letter to remove: ").lower()
removed=[s.replace(y,'') for s in letters]
print(removed)
#['p', '', 't', 'h', 'o', 'n']
I hope this help, unless its different from what you want. Then let me know. Otherwise, happy coding!
You don't need to create an empty list and then populate it with individual letters. Simply apply the list() function directly for the user input to create it:
letters = list(input('Choose word: ').lower())
print(letters)
For adding letters from the other user input, use the same approach with the .extend() method:
letters.extend(input('Choose word: ').lower()) # No need to use list() here
A simple one liner:
x = input().lower().split()
print(x)
here we are taking the input and then we are converting to lowercase and then using the split function which will split the string on white spaces you can split the string on whatever string you feel like just give the string you want to split on as the argument in the split function for example:
x = input().lower().split(',')
print(x)
this will split on the ',' so you can give the input in csv format
You may use the + operator (preferably in the form of an augmented assignment statement, i.e. +=, for extending the list to an iterable.
No need to use the list() function here, because the string is iterable:
letters = []
letters += input('Choose word: ').lower()
print(letters)
this outputs [['o', 'u', 't', 'p', 'u', 't']] meaning that the whole
list got appended as one item, but i want this to output ['o', 'u', 't', 'p', 'u', 't']
Based on you comment, you can use:
x = [*input('Choose word: ').lower()]
print(x)
# ['p', 'y', 't', 'h', 'o', 'n']
Demo

How to include spaces as characters in lists

This is my current code:
key = input("Enter the key: ")
sent = input("Enter a sentence: ")
print()# for turnin
print()
print("With a key of:",key)
print("Original sentence:",sent)
print()
#split = sent.split()
blank = [ ]
for word in sent:
for ch in word:
blank = blank + ch.split()
print(blank)
print()
What i have now gives me a list of all the letters in my sentence, but no spaces. If i use this...
for word in sent:
for ch in word:
print(ch.split())
It gives me a list of all characters including the spaces. Is there to get this result and have it equal a variable?
If you just want a list of all characters in the sentence, use
chars = list(sent)
What you're doing is definitely not what you think you're doing.
for word in sent:
This doesn't loop over the words. This loops over the characters. This:
for word in sent.split()
would loop over the words.
for ch in word:
Since word is a character already, this loops over a single character. If it weren't for the fact that characters are represented as length-1 strings, this would throw some kind of error.
sent is of type string. and when you iterate over a string this way:
for word in sent:
you get the individual characters, not the words.
Then you iterate over a single char:
for ch in word:
and get that very same char (!).
And then with that split() call you convert a non-blank character, say 'x' into a list with itself as element (['x']) and a blank characters into the empty list.
You probably want something along the lines of:
for word in sent.split():
....
But if what you want is to build a list of words, no need to iterate, that's exactly what sent.split() will get you!
And if what you want is a list of chars, do list(sent).
From help(str.split):
split(...)
S.split(sep=None, maxsplit=-1) -> list of strings
Return a list of the words in S, using sep as the
delimiter string. If maxsplit is given, at most maxsplit
splits are done. If sep is not specified or is None, any
whitespace string is a separator and empty strings are
removed from the result.
If you want individual characters of a string, pass it to list.
>>> list('This is a string.')
['T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 's', 't', 'r', 'i', 'n', 'g', '.']
I'm not 100% sure what you're asking, but it seems like....
blank = [ch for ch in sent]
...that's all you need....
Let me give you some sample Ins and Outs and see if that's what you want.
IN = "Hello world!"
OUT =>
['H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!']
Is that right?
string = "This here is a string"
>>> x = list(string) # I think list() is what you are looking for... It's not clear
>>> print x
['T', 'h', 'i', 's', ' ', 'h', 'e', 'r', 'e', ' ', 'i', 's', ' ', 'a', ' ', 's', 't', 'r', 'i', 'n', 'g']
>>> print string.split() # default arg is a space
['This', 'here', 'is', 'a', 'string']

Can it be done with recursion?

im trying to make my program run as i want it to, but i have some trouble with that, hope someone can help with that.
I wrote a program that takes a list of chars and assembles them to create words. Word ends when there is a " " in list. So it looks like that:
inp = ['r','e', 'e', 'l', ' ', 'y', 'e', 'l', 'l', 'o', 'w', ' ', 'g', 'e', 'l',' ', 'p','e','e','k']
outp = ['reel', 'yellow', 'gel', 'peek']
The code looks like this:
def mer(inp, outp=[]):
tail = 0
for item in inp:
if item == (" "):
inp[:tail] = ["".join(inp[:tail])]
outp.append(inp.pop(0))
inp.remove(item)
if ((" ") in inp) == False:
inp[:] = ["".join(inp[:])]
outp.append(inp.pop(0))
tail +=1
And now to get the output (in the case with the input like on top) i need to call mer two times. Is there a way to make it run untill the input list is empty, or maybe use a recursion?
It's just a programming exercise, so it can be probably all done better, but for now thats all i need.
You can use join and split:
>>> ''.join(inp).split()
['reel', 'yellow', 'gel', 'peek']
# recursion
from itertools import takewhile
def fun(x):
if not x:
return
y = list(takewhile(lambda i:i!=' ', x))
yield ''.join(y)
for z in fun(x[len(y)+1:]):
yield z
list(fun(['r','e', 'e', 'l', ' ', 'y', 'e', 'l', 'l', 'o', 'w', ' ', 'g', 'e', 'l',' ', 'p','e','e','k']))
I know you asked for a method using recursion, but the most pythonic method in this case is to join the characters together, then split them.
outp = "".join(input).split(" ")
And now to get the output (in the case with the input like on top) i need to call mer two times.
The problem with your algorithm is that you are modifying the list while you iterate over it. This is a naughty and unsafe thing to be doing.
After "reel" is put into outp, inp is ['y', 'e', 'l', 'l', 'o', 'w', ' ', 'g', 'e', 'l',' ', 'p','e','e','k']. But the next character that will be examined by the loop is - at least in the CPython implementation - not the 'y' of 'yellow', but the 'w'. This is because the iteration internally stores an index (which happens to be in sync with the tail variable that you update manually) and uses that to grab elements. The listiterator created behind the scenes to implement the for-loop is utterly unaware of changes to the list that it's iterating over, and thus can't adjust to keep the "same position" (and who knows what you really mean by that, anyway?).
You can see this for yourself if you add a couple of "trace" print statements to the code to show the state of the variables at various points.
Anyway, since the iterator is at the 'w' at this point, it will find the space next and extract 'yellow' just fine; but next it will move to the 'k' of "peek", missing the space after 'gel', and it won't run any of the code in your second if-case, either, because the space between 'gel' and 'peek' is still in the buffer (you didn't really think clearly enough about the real end condition).
If you really, really want to do everything the hard way instead of just writing ''.join(inp).split(' '), you could fix the problem by tracking a beginning-of-word and end-of-word index, slicing out sublists, joining them and putting the resulting words into the output, and leaving the input alone. While we're at it:
functions should use the return value to return data; passing in an outp parameter is silly - let's just return a list of words.
We can use the built-in enumerate function to get indices that match up with the list elements as we iterate.
I have no idea what "mer" means.
You use way too many parentheses, and comparing to boolean literals (True and False) is poor style.
So, the corrected code using the original algorithm:
def words_from(chars):
begin = 0 # index of beginning of current word
result = [] # where we store the output
for i, char in enumerate(chars):
if char == ' ':
result.append(''.join(chars[begin:i]))
begin = i + 1
# At the end, make one more word from the chars after the last space.
result.append(''.join(chars[begin:]))
return result
You should definitely use join and split for this, but since the question specifically asks for a recursive solution, here is an answer that uses one.
This is meant as an exercise in recursion only, this code should not be used.
def join_split(inp, outp=None):
if not inp:
return outp
if inp[0] == ' ':
return join_split(inp[1:], (outp or ['']) + [''])
if outp is None:
return join_split(inp[1:], [inp[0]])
outp[-1] += inp[0]
return join_split(inp[1:], outp)
>>> join_split(['r','e', 'e', 'l', ' ', 'y', 'e', 'l', 'l', 'o', 'w', ' ', 'g', 'e', 'l',' ', 'p','e','e','k'])
['reel', 'yellow', 'gel', 'peek']

Python: Problem with raw_input, turning the value I get into an array

I'm having issues with raw_input again, this time trying to turn the value I get into a list. Here is my code:
original = raw_input("Type is your input? ")
original_as_array = list('original')
print original_as_array
for i in range(0,len(original)):
print i
my print original_as_array literally prints ['o', 'r', 'i'.... etc]. If we pretend that my input is Hello World, I want original_as_array to output: ['H', 'e', 'l', 'l', 'o', ' ', 'W', 'o'... etc]. I think I'm making a tiny mistake. Can you point me in the right direction:)?
Quotes form a string literal.
original_as_array = list(original)
original = raw_input("Type is your input? ")
original_as_array = list(original) # no quotes. If you put quotes, you are turning it into a string.
print original_as_array
for i in original_as_array: # this is shorter way to iterate and print than your method
print i
Strings are already iterable, so you don't need to convert it to a list, so you can easily go :
original = raw_input("Type is your input? ")
# or if you really want a list
original_as_list = list(original) # NOT 'original', that's passing the string original not the value of original
for letter in original:
print letter

Categories

Resources