Inbuilt module implementing doubly linked list
Freeing nodes in doubly linked list
data structures - Doubly Linked list in Python - Stack Overflow
Trying to implement an efficient LinkedList class in Python
Hello, I have found it convenient to create a doubly linked list to iterate through a bunch of objects and store the them in order based on non numeric criteria.
I only care about the top 5 nodes so to eliminate the need to traverse a very long list, I want to just sever the nodes after 5.
My question is: do I have to delete the nodes somehow or can I just ground out the last node I care about? I have never really heard about memory management in python and want to make sure I’m not creating a leak and id prefer not to set all the nodes to none if I don’t have to
Given the fact that the problem definition specifies "pointers", python is not a suitable language to implement this. But you can use python variables as "pointers" (or rather references) because that is what they are; A python variable is just a name for or refrence to an object.
But if you want to implement in python, I would use a list ot tuples.
The first one is a list of (name, weight) tuples.
In [1]: data = [("Michael", 275), ("Tom", 150), ("Abe", 200)]
The order in this list doesn't matter. Just append new tuples to this list as they arrive.
Now the easy way to do it would be to make shallow copies (which reference the same tuples), and sort them appropriately just before you print them;
In [2]: namelist = [d for d in data]
In [3]: namelist.sort(key=lambda x: x[0])
In [4]: namelist
Out[4]: [('Abe', 200), ('Michael', 275), ('Tom', 150)]
and
In [5]: weightlist = [d for d in data]
In [6]: weightlist.sort(key=lambda x: x[1])
In [7]: weightlist
Out[7]: [('Tom', 150), ('Abe', 200), ('Michael', 275)]
Printing these in the correct sequence is now trivial.
But this is expressly forbidden in the exercise. So what you have to do is something like this;
- Create a new (
name,weight) tuple - Walk the list of tuples sorted by weight and compare the weight in the new tuple with the weight in the existing tuple (hint: use
enumerateso you get the index of the tuple in the list). As soon as you've found a weight that is greater than the weight of the listed tuple,insertthe new tuple in the weight-sorted list. - similar for the name-sorted list, but then using the name as the compare value.
Something like this;
In [10]: newvalue = ("Eric", 225)
In [11]: for index, (name, weight) in enumerate(weightlist):
....: if newvalue[1] < weight:
....: weightlist.insert(index, newvalue)
....: break
....:
In [12]: weightlist
Out[12]: [('Tom', 150), ('Abe', 200), ('Eric', 225), ('Michael', 275)]
Note that this algorithm assumes that weightlist is already in sorted order!
Another solution that is more in line of the assignment would be to use a dictionary for every person;
In [37]: newvalue = {"name": "Eric", "weight": 225, "nextname": None, "nextweight": None}
You will also need the data list to hold all the dictionaries.
And you will need two variables startname and startweight to hold the first name and lowest weight respectively.
After you have made a newvalue, you start with comparing newvalue["weight"] to startweight["weight"]. If the new weight is smaller than the startweight, then newvalue becomes the new startweight, and newvalue["nextweight"] should be set to the old startweight. If not, you move to the next item in the list and compare again. Note that if you want to insert in the chain, you have to change two nextweight attributes!
This is a double, singly linked list. Beginning with startweight and startname you can print both in order by walking both chains.
Here is how I would do it. I suggest that you create a new question or search around for how to read data from a text file.
class Node:
def __init__(self, name, weight):
self.name = name
self.weight = weight
self.prev_name = None
self.next_name = None
self.prev_weight = None
self.next_weight = None
class DLL:
def __init__(self):
self.head = Node(None, None)
self.tail = Node(None, None)
self.head.next_name = self.tail
self.head.next_weight = self.tail
self.tail.prev_name = self.head
self.tail.prev_weight = self.head
def add(self, name, weight):
node = Node(name, weight)
# add by name
p = self.head
while (p.next_name != self.tail) and (p.next_name.name < name):
p = p.next_name
node.next_name = p.next_name
node.prev_name = p
p.next_name = node
node.next_name.prev_name = node
# add by weight
p = self.head
while (p.next_weight != self.tail) and (p.next_weight.weight < weight):
p = p.next_weight
node.next_weight = p.next_weight
node.prev_weight = p
p.next_weight = node
node.next_weight.prev_weight = node
def printByName(self):
p = self.head
while p.next_name != self.tail:
print(p.next_name.name, p.next_name.weight)
p = p.next_name
def printByWeight(self):
p = self.head
while p.next_weight != self.tail:
print(p.next_weight.name, p.next_weight.weight)
p = p.next_weight
return
And some results:
D = DLL()
D.add("Jim",150)
D.add("Tom",212)
D.add("Michael",174)
D.add("Abe",199)
D.printByName()
Abe 199
Jim 150
Michael 174
Tom 212
D.printByWeight()
Jim 150
Michael 174
Abe 199
Tom 212