I wrote a function that adds items in a list, but my professor says to try and write it in a simpler way because he says I take too many steps. Is there any other way to write this?
def additems(self, item):
"""Add <item> to this PriorityQueue.
@type self: PriorityQueue
@type item: object
@rtype: None
>>> pq = PriorityQueue()
>>> pq.additems("yellow")
>>> pq.additems("blue")
>>> pq.additems("red")
>>> pq.additems("green")
>>> pq._items
['blue', 'green', 'red', 'yellow']
"""
# TODO
#only insert if the list isn't already empty
if not self.is_empty():
i = 0
#Look for the lowest priority place to insert the item
while i < len(self._items):
if item <= self._items[i]:
self._items.insert(i, item)
#exit the loop if it inserts
i = len(self._items)
elif item >= self._items[-1]:
self._items.append(item)
#exit the loop if it inserts
i = len(self._items)
i += 1
else:
self._items.append(item)
1 Answer 1
You don't present the entire code for the class here, but the usage of self
and the doctests within the docstring indicates that you are actually using a class. As such my first order would be that in the initialisation of the class you always create the _items
list, which would remove the need to check whether there are elements or not when adding elements.
To use i = len(self._items)
to terminate the loop is a hackish solution. It would be better to use break
instead. But while
and for
(and actually try ... except
) allows for the usage of else
which can help out in this particular case. In short, if the loop terminates ordinarily, the else
part is executed, if you break
out of it, it'll not be executed.
In stead of doing the while i < len(self._items)
loop, which requires calculating the length multiple times, and doesn't look to Pythonic, I would suggest using for i, item in enumerate(self._items)
. This loop construct loops over all the elements (if any) and gives the index of the current element (due to the use of enumerate()
).
Lastly, naming the method additems()
when you only add one element is misleading and not following standards. A better name would be add_item()
.
This leads to the following code:
class PriorityQueue(object):
def __init__(self):
self._items = []
def add_item(self, new_item):
"""Add items into queue at correct place."""
for i, item in enumerate(self._items):
if new_item < item:
self._items.insert(i, new_item)
break
else:
self._items.append(new_item)
def main():
pq = PriorityQueue()
pq.add_item("yellow")
pq.add_item("blue")
pq.add_item("red")
pq.add_item("green")
print(pq._items)
if __name__ == '__main__':
main()
I'm sorry that the environment I tested this in doesn't support doctests, but this does output the correct list of ['blue', 'green', 'red', 'yellow']
.
return self._items.insert(0, item)
\$\endgroup\$