Reverse the order of words in python using stack - python

I am trying to use stack to reverse the order like if j="this is sentence" so the output will be "sentence is this" to do this I try to put it in stack and then pop them out like
stack.push(j.split(' '))
and then pop it as
while not stack.is_empty()
print stack.data.pop(),
but what stack.push(j.split(' ')) does it puts the whole sentence as single entity in the stack like
[['this','is','a','sentence']]
and hence when i pop it it gives result
['this','is','a','sentence']
means nothing reversed at all in nutshell.so how should i split and push the word in stack so that i can reverse the order of words.

stack.push places the given element/argument on top of stack. For you case the element/argument is whole list. You need to push each element of list seperately. So, replace:
stack.push(j.split(' '))
by:
for i in j.split():
stack.push(i)

First of all stack.push(j.split(' ')) doesnt return splited words. It returns an object with splited words. So that when you push j.split(' ') in a stack, it actually push all words as an object. In the end when you poped up it returns the last entry and that is the object ['this','is','a','sentence'].
class Stack():
def __init__(self):
self.items = []
def isEmpty(self):
return self.items == []
def push(self, item):
return self.items.append(item)
def pop(self):
return self.items.pop()
def getElements(self):
return self.items
def peek(self):
return self.items[len(self.items)-1]
def size(self):
return len(self.items)
j="this is sentence"
stack = Stack()
jj = j.split(' ')
for word in jj:
stack.push(word)
print stack.getElements()
print stack.peek() # shows you latest (last) value of array
print stack.pop()
In the code you'll find the object is traversed and pushed each word into stack. Then just simply pop each word.

stack.push(*j.split(' '))
Python does not consider the list returned by split as a list of arguments unless you explicitly specify that using an asterisk. Otherwise it will simply push a list on the stack

Related

How to find/delete duplicate items in stack

The items inside the stack should be unique. Is there a way I can delete the duplicate item inside the stack? And inform the user that his input is already inside the stack?
Here is my code:
class Node:
def __init__(self, key):
self.left = None
self.right = None
self.val = key
def printPreorder(root):
if root:
print(root.val),
printPreorder(root.left)
printPreorder(root.right)
class stack:
def __init__(self):
self.items = []
def push(self, item):
return self.items.append(item)
def pop(self):
return self.items.pop()
print ("Create 3 words using the letters:")
root = Node('n')
root.right = Node('o')
root.left = Node ('w')
printPreorder(root)
print("-----------------------------------")
s1 = stack()
while (s1.size() <3):
FirstList = (input("Enter the word you created: ")).lower()
if FirstList == 'won' or FirstList == 'own' or FirstList == 'now':
s1.push(FirstList)
print(s1.items)
else:
print('Try another word!')
Ideally no you cannot traverse through a stack to find duplicate elements.
But since you are using a list for your stack implementation, you can traverse through it and find duplicate elements but this is not a good idea.
Instead, you can use another data structure, for example, a set can be used to keep track of all the unique elements you have seen so far. Every time .push() is called, you can check if the element is already present in the set. If it is not present, then you can add it to both the stack and set. If present, you can inform the user that it is already present in stack.
And remember to remove the element from the set when you pop from the stack.
You can use set to store unique values. A simple way to check if the stack has unique elements is to compare the size of the set of stack elements and the list of stack elements (since your implementation of a stack is a list).
def isDuplicate(self):
return len(set(self.items())) != len(self.items())
To check if there's a duplicate element in the stack (implemented as a list), you can write an implementation that inserts your elements into a set, and at every step checks whether the element already exists inside the list.
def removeDuplicate(self):
temp_set = set()
for item in self.items():
if item in temp_set:
return item
return None
And then you can remove that duplicate element from the stack using self.items().pop(self.removeDuplicate())

Object list index is not being updated: Index Error: list

I have a class which I will keep omit unimportant information:
class BuildMap:
def __init__(self):
#Constructor
self.nodes = []
def indexmap(self):
for node in self.nodes:
print(int(node),":",nodes[node])
def delnode(self,num):
del self.nodes[num]
for edge in self.edges:
if num in self.edges[edge]:
self.edges[edge].remove(num)
del self.edges[num] #Deletes the list associated with the number
del nodes[int(num)] #Deleted the word associated with the node number
for dist in list(self.distance.keys()):
if num in dist:
del self.distance[dist]
Outside of the class:
def delnode():
print("Please specify the city you would like to remove: ")
GPSMap.indexmap()
num = input("City Number: ")
if int(num) >= len(nodes):
print("Sorry that number does not match")
delnode()
GPSMap.delnode(int(num))
The problem I am having is that after deleting one "node" and doing all the code I've made to clean up my other data structures I receive
File "C:/Users/gibbo/PycharmProjects/main.py", line 52, in indexmap
print(int(node),":",nodes[node])
IndexError: list index out of range
I have done some debugging and noticed my index isn't stopping with the length of the list and is going past after an node has been deleted as if the index hasn't been updated or my for loop:
for node in self.nodes:
Isn't using the number of nodes in the list as the index.
node is a node, not an integer. Since you haven't included the definition of the object, we don't know what happens when you convert it to an integer, but I'm pretty sure you're not going to like the result. When you use that as an index, the result is almost certain to be well outside the range of your list.
To see the actual effect, separate your print statement:
print(int(node))
print(nodes[node])
Overall, you should recognize that node is the node from the list, not its position in the list. Use node directly as the object you want.
def indexmap(self):
for node in self.nodes:
# list elem -^ ^- list
print(int(node),":",nodes[node])
# ^- It should be int, not elem.
so, fix it.
def indexmap(self):
for (i,node) in enumerate(self.nodes):
print("{}:{}".format(i, node))

stack function python error

I created the following stack class for a project and am having trouble getting it to function properly. I can't tell if i made the error or it is an error in the main function i was given by my TA, anyways here is my code:
class Stack:
#takes in the object as input argument
#will not return anything
def __init__(self):
#initialise an instance variable to an empty list.
self.items=[]
#takes in the object as input argument
#return value Type: True or False
def isEmpty(self):
#check if the list is empty or not. If empty, return True else return False
if self.items == []:
return True
else:
return False
#takes in the object as the first argument
#takes the element to be inserted into the list as the second argument
#should not return anything
def push(self, x):
#add the element to be inserted at the end of the list
self.items.append(x)
#takes in the object as the input argument
#if the list is not empty then returns the last element deleted from the list. If the list is empty, don't return anything
def pop(self):
#check if the list is Empty
#if Empty: print the list is empty
#if the list is not empty, then remove the last element from the list and return it
if self.isEmpty()==True:
print("the list is empty")
else:
return self.items.pop()
#takes in the object as the input argument
#should not return anything
def printContents(self):
#if the list is not empty, then print each element of the list
print("The content of the list is", self.items)
Based on the comments can anyone give me any advice on how I might make this work more appropriately? Sorry I am not a computer scientist and i am trying my hardest to understand classes and functions for my python class.
from stack import *
def main():
s = Stack()
s.push(1)
s.pop()
s.pop()
s.push(2)
s.push(3)
s.push(4)
s.printContents()
main()
You should take a good look in spaces and alignment. For example printContents is not properly aligned. Note the proper alignment is very, very important in python.
Also you are not printing in printContents. This should work:
class Stack:
#takes in the object as input argument
#will not return anything
def __init__(self):
#initialise an instance variable to an empty list.
self.items=[]
#takes in the object as input argument
#return value Type: True or False
def isEmpty(self):
#check if the list is empty or not. If empty, return True else return False
if self.items == []:
return True
else:
return False
#takes in the object as the first argument
#takes the element to be inserted into the list as the second argument
#should not return anything
def push(self, x):
#add the element to be inserted at the end of the list
self.items.append(x)
#takes in the object as the input argument
#if the list is not empty then returns the last element deleted from the list. If the list is empty, don't return anything
def pop(self):
#check if the list is Empty
#if Empty: print the list is empty
#if the list is not empty, then remove the last element from the list and return it
if self.isEmpty():
print("the list is empty")
else:
return self.items.pop()
#takes in the object as the input argument
#should not return anything
def printContents(self):
#if the list is not empty, then print each element of the list
print("the contents of the list are", self.items)
def main():
s = Stack()
s.push(1)
s.pop()
s.pop()
s.push(2)
s.push(3)
s.push(4)
s.printContents()
main()
You can see it working online here:
https://repl.it/BZW4
Everybody has to start sometime so no worries, and I hope you are not offended by my extended critique, as I am just trying to be helpful.
You probably want the top declaration to be:
class Stack(object):
Leaving off the (object): part is a deprecated form that makes certain features of the class different in ways you probably don't want.
Secondly, declaring an isEmpty method is not really a normal "pythonic" approach. The strong expected python convention is to simply check the truth value of your object, with empty being False. Typical python users of your class will not expect an isEmpty method. You can control the behavior of your object's truth value by defining the special nonzero which you could write like this:
def __nonzero__(self):
return bool(self.items)
This way somebody could use your class like:
stack = Stack()
stack.append("apple")
stack.append("pear")
if stack:
print "stack has stuff in it"
else:
print "stack is empty"
Moreover, there are other things you should overload to make a good stack class. For example you ought support len(stack) and you ought to be able to iterate over your stack. You can define special len and iter methods to do this. Notice if you define the len then you don't need to define the iszero (python will consider your stack False if len returns 0 and you have not defined iszero).
Your printContents method will not print or write anything without a print or write statement, but will return the last element in the stack and throw an index error if the stack is empty. To iterate over each item and print it you could write it like this (from the top item of stack to the first one):
def printContents(self):
for item in reversed(self.items):
print item
However it would be more pythonic to define an iteration method and the use that, so your user can iterate over your stack and print it themselves:
def __iter__(self):
for item in self.items:
yield item
# later in code .....
stack = Stack()
stack.append("apple")
stack.append("pear")
for item in stack:
print item
Hopefully these tips may prove useful. Keep at it, and you will get it before long.
Modify your pop definition in class to this
def pop(self):
#check if items is empty
if len(self.items)==0:
#if empty
return "Nothing to pop"
else:
#if not empty
return str(self.items.pop())+" Popped"

List class retaining old values for new list Python

I have created a list class with a few simple methods.
class ListQ(object):
"""List object creation"""
def __init__(self, earlier_list=[]):
self.list=earlier_list
def isEmpty(self):
"""checks if list is empty"""
if len(self.list)==0:
return(True)
else:
return(False)
def put(self, new_item):
"""puts new_item last in list"""
self.list.append(new_item)
def get(self):
"""returns the next item in line"""
self.first_item = self.list.pop(0)
return self.first_item
I also have a function to help create these lists. (Helping to solve a magic card trick btw)
def create_card_list(card_list=None):
"""creates listQ of cards from user input"""
if card_list!=None: #if user already has list of cards
for item in card_list:
item=replace_card_strings(item) #replaces any strings in list
if item == False:
print('One of your cards does not exist, list creation failed')
return(False)
cards=ListQ(card_list)
The replace_card_strings() function has been properly tested and I do not believe it's at fault but here it is anyway.
def replace_card_strings(word):
"""replaces strings of words with their numbers and returns edited list"""
if type(word)!=int:
if word.lower()=='one':
word=1
elif word.lower()=='two':
word=2
elif word.lower()=='three':
word=3
elif word.lower()=='four':
word=4
elif word.lower()=='five':
word=5
elif word.lower()=='six':
word=6
elif word.lower()=='seven':
word=7
elif word.lower()=='eight':
word=8
elif word.lower()=='nine':
word=9
elif word.lower()=='ten':
word=10
elif word.lower()=='jack':
word=11
elif word.lower()=='queen':
word=12
elif word.lower()=='king':
word=13
elif word.lower()=='ace':
word=1
else:
word=False #if card doesnt exist
return(word)
When I run the following test is when the problem start.
cards=create_card_list(['one', 2, 3])
one=cards.get()
two=cards.get()
three=cards.get()
print(one, two, three)
if one==1 and two==2 and three==3:
print("create_card_list gives the correct answer")
else:
print("create_card_list gives the wrong answer")
It prints that the function has given the wrong answer and
the print(one, two, three) prints one 2 3 which is the original list.
Anybody have an idea where I've messed up?
You're not replacing items in the list, only in the loop's context:
Replace the entire loop:
for item in card_list:
item=replace_card_strings(item) #replaces any strings in list
....
Which does not do anything to the list (it does not "replace" the item).
With python's map which is used in order to apply a function to an iterable and create a list of results:
card_list = map(replace_card_strings, card_list)
If you don't want to use map you can use list comprehension:
card_list = [replace_card_strings(card_str) for card_str in card_list]
Now you'll have:
def create_card_list(card_list=None):
"""creates listQ of cards from user input"""
if card_list != None:
card_list = map(replace_card_strings, card_list)
cards=ListQ(card_list)
Tip:
You can replace the lengthy function replace_card_strings:
def replace_card_strings(word):
"""replaces strings of words with their numbers and returns edited list"""
word = word.lower()
string_to_int = {"one":1, "two":2 ...}
return word in string_to_int and string_to_int[word]
This works since and returns the last Truth-y result or the first False-y result.
You can also use dict.get:
# return word in string_to_int and string_to_int[word]
# try and read value from dict, return False otherwise
return string_to_int.get(word, False)
Which is cleaner (thanks #padraic).
Tip 2: You don't want two places referencing, and possibly mutating, the same list. It seems like you're keeping a reference to the same list that's used to construct a card list outside the generated object. This is prone to errors. What you should do is instead copy the list when it's passed:
def __init__(self, earlier_list=[]):
self.list=earlier_list[:]
Tip 3: python has a known "gotcha" with mutable default argument, which is exactly what you use here (earlier_list=[]). This is prone to errors as well since python binds default arguments once. You should instead have:
def __init__(self, earlier_list=None):
# copy passed list or create a new one if none passed.
self.list=earlier_list[:] if earlier_list else []

A function accepting two stacks as parameters and return a Python list

Please help me write a function to add numbers from two stacks by the position and return the result as a list.
Code here are operations on the stack:
stack_a = Stack()
stack_a.push(1)
stack_a.push(2)
stack_b = Stack()
stack_b.push(6)
stack_b.push(8)
result = add(stack_a , stack_b)
print(result)
and here is the definition of the Stack class
class Stack:
def __init__(self):
self.items = []
def is_empty(self):
return self.items == []
def push(self, item):
self.items.append(item)
def pop(self):
return self.items.pop()
def peek(self):
return self.items[len(self.items) - 1]
def size(self):
return len(self.items)
This is what I have done so far:
def add(first, second):
return first.pop() + second.pop()
I got 10 which only accounts for addition of stack_a.push(2) and stack_a.push(10). Please help me improve on what I got so far.
Your code will be the same, excluding the extra add_all function which i added. It pops last item of two stacks that you provide, adds them, and appends them in a list that you get as a result.
Note that the order in the returned list is last to first, like in your add function.
def add(first, second):
return first.pop() + second.pop()
def add_all(first_stack, second_stack):
"""
Pops last elements of two stacks and adds them,
until all elements are added.
Returns:
list
"""
returned_lst = []
# Determine the how many items will be added.
# (ensures that no errors are raised if two stacks have different size)
number_of_items_to_be_added = min(first_stack.size()), second_stack.size())
# If you are using Python 2.x use 'xrange' instead of 'range'
for element in range(number_of_items_to_be_added):
returned_lst.append(add(first_stack, second_stack))
return returned_lst
stack_a = Stack()
stack_a.push(1)
stack_a.push(2)
stack_b = Stack()
stack_b.push(6)
stack_b.push(8)
stack_b.push(9)
result = add_all(stack_a, stack_b)
print(result)
Let me know if i misunderstood what you need, or if you need something more.
You will need to iterate over the elements of the stack and as we see that the elements of the stack are stored in the .items , which is a list so we find out the length of the list and iterate over each index and add the corresponding elements.
If the length of both the stacks is unequal then it will iterate upto the length of the minimum of the two.
def add(first, second):
answer = []
for i in xrange(min(len(first.items), len(second.items))):
answer.append(first.items[i]+second.items[i])
return answer

Categories

Resources