How to find/delete duplicate items in stack - python

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())

Related

Finding lowest odd number in a Linked List in python

I am newly learning about Linked Lists and my assigment requires me to make a function that returns the lowest odd number...and I think I have done that in my get_min_odd function.
I believe my code is only checking the first and second element of the linked list so my question is how can I iterate through a linked list to find the lowest odd number? I would think a for loop but I don't understand what list I'm iterating through...which brings up another question, where are the elements in a linked list stored if not in a list, array, string, etc.?
class LinkedList:
def __init__(self):
self.head = None
#def.....
def add_all(self, a_list):
newNode = Node(a_list)
newNode.next = self.head
self.head = newNode
for i in a_list:
self.next = i
def add_all(self, a_list):
for i in range(len(a_list)):
self.add(a_list[i])
def get_min_odd(self):
lst = []
if self.head.data % 2 == 1:
lst.append(self.head.data)
elif self.head.next.data % 2 == 1:
lst.append(self.head.next.data)
else:
return 999
return min(lst)
my_list = LinkedList()
my_list.add_all([1, 4, -3, 6, 9, 2, 10001, 25, 19, 20])
print(my_list.get_min_odd())
A few issues:
You have two methods that are called add_all. This means the first one will be lost. You actually need an add method instead of that first add_all. And it should not take a list as value, but just a single numeric value. That method should not have to loop (Moreover, assigning i to the same next attribute over and over again makes no sense).
get_min_odd is indeed too much fixed on the first and second node. They might not even exist when the list is short or empty. To loop over a linked list, you need a name that first equals the head node, but then traverses along the next attributes to the next node, and then the next, ... until it reaches the end.
get_min_odd should not create a list with values. That defeats the purpose of a linked linked list. Instead that code should immediately update the minimum it has while traversing the linked list.
Here is the updated code for the two methods that needed correction:
def add(self, value): # name and arg name correction
newNode = Node(value)
newNode.next = self.head
self.head = newNode
and:
def get_min_odd(self):
result = None
node = self.head
while node: # as long as the end of the list is not encountered...
if node.data % 2 == 1:
# adjust the result to the minimum data encountered so far
result = node.data if result is None else min(result, node.data)
node = node.next # traverse to next node
return result

RecursiveList Python

So i'm learning about RecursiveLists and our prof has given us a init for the recursivelist class
class RecursiveList:
# === Private Attributes ===
# _first:
# The first item in the list.
# _rest:
# A list containing the items that come after
# the first one.
_first: Optional[Any]
_rest: Optional[RecursiveList]
# === Representation Invariants ===
# _first is None if and only if _rest is None.
# This represents an empty list.
def __init__(self, items: list) -> None:
"""Initialize a new list containing the given items.
The first node in the list contains the first item in <items>.
"""
if items == []:
self._first = None
self._rest = None
else:
self._first = items[0]
self._rest = RecursiveList(items[1:])
now I want to mutate the list by inserting an item to the front of the list but I can't wrap my head around how to do so. I understand that self._rest stores the rest of the list recursively and also that I should move the value of self._first into self._rest, but how do I move an int and turn it so that the recursive function has the rest of them?
def insert_first(self, item: object) -> None:
"""Insert item at the front of this list.
This should work even if this list is empty.
"""
You make a new RecursiveList (btw: This is usually called a Linked List) that you copy your current value to, make its rest point to your current rest, overwrite your own element with the element to be inserted, and set your rest to the new list.
Something like:
def insert_first(self, item: object) -> None:
"""Insert item at the front of this list.
This should work even if this list is empty.
"""
if self._first is None:
# handle case where list is "empty"
self._first = item
else:
new = RecursiveList()
new._first = self._first
new._rest = self._rest
self._first = item
self._rest = new
Before:
1:"e" -→ 2:"l" -→ 3:"l" -→ 4:"o"
After:
1:"h" 2:"l" -→ 3:"l" -→ 4:"o"
| ↑
└→5:"e" -┘
Note that this process is a what is called constant-time operation, because it doesn't matter how large the list is: this process always takes roughly the same amount of time. This (constant-time insertion at the beginning of the list) is somewhat unique to Linked Lists, and does not apply to Python's normal lists, which are based on arrays.

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"

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

Reverse the order of words in python using stack

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

Categories

Resources