I am currently learning DS in python. I was creating class for stack.
I had couple of questions-
What type of coding skills is required for me to be an expert in Data Structures in python? Is it using the in-built structures of python or creating the basic data structures like stack, queue, linked lists, graphs etc.?
How can I check whether the elements of a list are integer or not so that I can pop them?
class Stack():
def __init__(self):
self.items = []
def isEmpty(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)
def show(self):
return self.items
lt = ['a', '1', '2', 'b', '3']
a = Stack()
for i in lt:
a.push(i)
for j in lt:
if not j.isdigit():
a.pop()
a.show()
how can I use the if statement here so that all the non-integer items can be popped from the list?
the if j!=%d is throwing an error
You don't need to pop from a, since you didn't add anything to it. Here's how you'd write that as a loop:
lst = ['a','1','2','b','3']
a = []
for i in lst:
if not i.isdigit():
a.push(i)
Better is the list comprehension I cited in the comments:
lst = ['a','1','2','b','3']
a = [i for i in lst if not i.isdigit()]
Note that you should not name your own variables list, since that hides the Python built-in type.
Answer Question No 1:
in-built structures of python is not a solution to understand data structure. so if you want really improve your skill on data structure and algorithm then defiantly do it manually. and under stand core concept how stack, link list, queue different type of sorting works. after clear concept understand BFS , DFS, shortest path find out algorithm and also different type of algorithm. You will achieved the knowledge about time complexity and space complexity of algorithm. so don't go built in structure if you have know idea about data structure and algorithm.
Answer Question No 2:
class Stack():
def __init__(self):
self.items = []
def isEmpty(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)
def show(self):
return self.items
lt = ['a', '1', '2', 'b', '3']
a = Stack()
for j in lt:
if not j.isdigit():
a.push(j)
a.show()
Related
I want to implement my own type of list called Stack. I also want to add slicing functionality with the __getitem__ method like so:
class Stack():
def __init__(self):
self.items = []
def __getitem__(self, slc):
return self.items[slc]
def append(self, item):
self.items.append(item)
Now if I create a Stack instance and append some elements to it I get the Stack type:
st = Stack()
st.append('hi')
st.append('bye')
st.append('hello')
print(type(st)) # Stack type
but if I slice my Stack, it becomes a list again:
st_sliced = st[1:2]
print(type(st_sliced)) # List type
how can I make st_sliced to stay Stack type after slicing?
return self.items[slc] return a list - this is why the type is not a Stack anymore.
The code below keep the type as Stack.
class Stack:
def __init__(self, items=None):
if items is None:
items = []
self.items = items
def __getitem__(self, slc):
return Stack(self.items[slc])
def append(self, item):
self.items.append(item)
st = Stack()
st.append('hi')
st.append('bye')
st.append('hello')
print(type(st))
st_sliced = st[1:2]
print(type(st_sliced))
I don't understand the difference between just using a list and appending and popping from it or creating a class which does the same thing?
list = []
list.append(1)
list.append(2)
class myStack:
def __init__(self):
self.container = [] # You don't want to assign [] to self - when you do that, you're just assigning to a new local variable called `self`. You want your stack to *have* a list, not *be* a list.
def isEmpty(self):
return self.size() == 0 # While there's nothing wrong with self.container == [], there is a builtin function for that purpose, so we may as well use it. And while we're at it, it's often nice to use your own internal functions, so behavior is more consistent.
def push(self, item):
self.container.append(item) # appending to the *container*, not the instance itself.
def pop(self):
return self.container.pop() # pop from the container, this was fixed from the old version which was wrong
def peek(self):
if self.isEmpty():
raise Exception("Stack empty!")
return self.container[-1] # View element at top of the stack
def size(self):
return len(self.container) # length of the container
def show(self):
return self.container # display the entire stack as list
s = myStack()
s.push('1')
s.push('2')
It looks the same to me so wouldn't the first code be a better implementation of a stack?
This question already has answers here:
How to print instances of a class using print()?
(12 answers)
Closed 3 years ago.
can anybody explain why it is showing me and how to print it?
what am I doing wrong and how to print this object reference?
i have also tried printing new_list(inside sort() ) but still the same
I am printing list then why it is not showing
I know some of the people asked before about related to this...but still I didn't get it.
class node(object):
def __init__(self, d, n=None):
self.data=d
self.next_node=n
def get_data(self):
return self.data
def set_data(self,d):
self.data=d
def get_next(self):
return self.next_node
def set_next(self, n):
self.next_node=n
def has_next(self):
if self.get_next() is not None:
return True
else:
False
class LinkedList(object):
def __init__(self, r=None):
self.root=r
self.size=0
def get_size(self):
return self.size
def add(self,d):
new_node = node(d, self.root)
self.root = new_node
self.size+=1
def sort(self):
if self.size>2:
newlist = []
this_node = self.root
newlist.append(this_node)
while this_node.has_next():
this_node = this_node.get_next()
newlist.append(this_node)
newlist = sorted(newlist ,key = lambda node: node.data,reverse=True)
newLinkedList = LinkedList()
for element in newlist:
newLinkedList.add(element)
return newLinkedList
return self
new_list=LinkedList()
new_list.add(10)
new_list.add(20)
new_list.add(30)
new_list.sort()
i expected that it will print list print a list
but it is showing <main.LinkedList object at 0x00E20BB0>
how to print this object ?
You are not printing out node values of the linked list instead you are printing out the return value of the sort() function which is an object of the class LinkedList.
If you want to print the linked list, you have to traverse the list and print out each node value individually.
Here is the recursive solution of how you can print a linked list.
def print_list(head):
if head != null:
print(head.val)
print_list(head.next)
You can call this method after calling the sort function
Actually my sort algorithm works, but there is a problem.
I have a class namely SortedItem which includes
def __init__(self, point, cost):
self.coordinate = point
self.cost = cost
and I have also priority queue which sorts the this SortedItem by its cost:
class PriorityQueue:
def __init__(self):
self.items = []
def isEmpty(self):
return self.items == []
def sortComparatorByCost(self, item):
return item.cost
def enqueue(self, item):
self.items.append(item)
self.items.sort(key=self.sortComparatorByCost, reverse=True)
def dequeue(self):
return self.items.pop()
def returnQueueAsString(self):
queue_str = ""
for eachItem in self.items:
queue_str += str(eachItem) + " "
return queue_str
def isQueueContainsElement(self, element):
for eachElement in self.items:
if eachElement[0] == element:
return True
return False
The problem occurs here:
- I have defined some order to add queue. Let's say I am adding this objects to the queue:
obj1 = SortedItem((1,0), 10))
queue.enqueue(obj1)
obj2 = SortedItem((2,0), 15))
queue.enqueue(obj2)
obj3 = SortedItem((2,1), 15))
queue.enqueue(obj3)
Now I have to get objects from queue in this order (obj1, obj2, obj3).
However python built-in sort function sort these objects like this: (obj1, obj3, obj2) (because obj2 and obj3 has the same cost)
How can i solve this issue. I mean If 2 objects cost is the same, I should get the first added one.
Note that: I have just created a simple example of my problem. If you try this code you may get the objects in this order: obj1, obj2, obj3
Instead of sorting the items in reverse order and removing them from the right,
def enqueue(self, item):
self.items.append(item)
self.items.sort(key=self.sortComparatorByCost, reverse=True)
def dequeue(self):
return self.items.pop()
you could remove them from the left. That would avoid reversing the order of insertion of the items with the same cost.
def enqueue(self, item):
self.items.append(item)
self.items.sort(key=self.sortComparatorByCost)
def dequeue(self):
return self.items.pop(0)
Removing items from the beginning of a list is not efficient, however, so you could better use a deque (replacing pop(0) by popleft()) to fix that. A deque on the other hand, has no in-place sort() method, so would need to replace self.items.sort() by self.items = deque(sorted(self.items)) as well.
I'm doing some basic Python programming practice exercises and tried to implement a queue (using lists). Unfortunately, I'm getting behavior for my isempty() function that I don't understand. When running the code below, the last two lines give different answers: A yields False, while B yields True. Why doesn't A also yield False?
class Queue:
def __init__(self):
self.items = []
def push(self,item):
self.items.insert(0,item)
def pop(self):
return self.items.pop()
def size(self):
return len(self.items)
def isempty(self):
return self.size == 0
q = Queue()
q.push("a")
q.push("b")
print(q.pop())
print(q.isempty())
print(q.pop())
print(q.isempty()) # shouldn't this (A)...
print(q.size()==0) # ...and this (B) yield the same answer?
Just change your isempty() method to:
def isempty(self):
return self.size() == 0
Your implementation of Queue.isempty() is checking to see if the method size is equal to the integer 0, which will never be true.
class Queue:
def __init__(self):
self.items = []
def push(self,item):
self.items.insert(0,item)
def pop(self):
return self.items.pop()
def size(self):
return len(self.items)
def isempty(self):
return self.size == 0
q = Queue()
print(q.size)
Produces:
<bound method Queue.size of <__main__.Queue object at 0x02F4EA10>>
The easiest solution is to use Christopher Shroba's suggestion to modify your Queue.isempty() implementation to use the list's size method.