leetcode/notebooks/collections/deque.ipynb

327 lines
6.3 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Deque"
]
},
{
"cell_type": "code",
"execution_count": 84,
"metadata": {},
"outputs": [],
"source": [
"from collections import deque"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Deque stands for double-ended queue. Can be used for fast, O(1) FIFO/LIFO. Internally implemented using doubly-linked lists of fixed-length blocks.\n",
"\n",
"Deques can be created from another sequence."
]
},
{
"cell_type": "code",
"execution_count": 85,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"a\n",
"g\n"
]
}
],
"source": [
"d = deque('abcdefg')\n",
"\n",
"print(d[0])\n",
"print(d[-1])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can extend a deque instance with another sequence either at the end or beginning"
]
},
{
"cell_type": "code",
"execution_count": 86,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"deque(['x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'])\n"
]
}
],
"source": [
"d.extend('hij')\n",
"d.extendleft('zyx')\n",
"\n",
"print(d)"
]
},
{
"cell_type": "code",
"execution_count": 87,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"deque(['w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'])\n"
]
}
],
"source": [
"d.append('k')\n",
"d.appendleft('w')\n",
"\n",
"print(d)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Can remove items from either ends using `pop` and `popleft`"
]
},
{
"cell_type": "code",
"execution_count": 88,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Popped rightmost item: d\n",
"Popped left most item: a\n"
]
}
],
"source": [
"d = deque('abcd')\n",
"\n",
"print(\"Popped rightmost item:\", d.pop())\n",
"print(\"Popped left most item:\", d.popleft())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Identical items can be removed using `.remove()`"
]
},
{
"cell_type": "code",
"execution_count": 89,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"deque(['b', 'c', 'd'])\n"
]
}
],
"source": [
"d = deque('abcd')\n",
"\n",
"d.remove('a')\n",
"print(d)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Raises `IndexError` if nothing left to remove"
]
},
{
"cell_type": "code",
"execution_count": 90,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"d c b a "
]
}
],
"source": [
"s = deque('abcd')\n",
"\n",
"while True:\n",
" try:\n",
" print(s.pop(), end=\" \")\n",
" except IndexError:\n",
" break"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"⭐️ Rotate a given collection"
]
},
{
"cell_type": "code",
"execution_count": 91,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"deque(['c', 'd', 'a', 'b'])\n",
"deque(['a', 'b', 'c', 'd'])\n"
]
}
],
"source": [
"d = deque('abcd')\n",
"\n",
"d.rotate(2)\n",
"print(d)\n",
"\n",
"d.rotate(-2)\n",
"print(d)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"⭐️ Deque size can be constrained using `maxlen`. Useful when dealing with streams of values but we just need to keep latest `n` items"
]
},
{
"cell_type": "code",
"execution_count": 92,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Left deque: deque([4, 3, 2], maxlen=3)\n",
"Right deque: deque([2, 3, 4], maxlen=3)\n"
]
}
],
"source": [
"import random\n",
"\n",
"ld = deque(maxlen=3)\n",
"rd = deque(maxlen=3)\n",
"\n",
"for i in range(5):\n",
" ld.appendleft(i)\n",
" rd.append(i)\n",
"\n",
"print(\"Left deque:\", ld)\n",
"print(\"Right deque:\", rd)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Deque is thread-safe, so can be consumed from both ends at same-time."
]
},
{
"cell_type": "code",
"execution_count": 96,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" Left: 0\n",
" Right: 4\n",
" Left: 1\n",
" Right: 3\n",
" Left: 2\n",
" Right: Done\n",
" Left: Done\n"
]
}
],
"source": [
"import threading\n",
"import time\n",
"\n",
"items = deque(range(5))\n",
"\n",
"def consume(direction, get_next):\n",
" while True:\n",
" try:\n",
" next = get_next()\n",
" print(f\"{direction:>8}: {next}\")\n",
" time.sleep(0.1)\n",
" except IndexError:\n",
" break\n",
" \n",
" print(f\"{direction:>8}: Done\")\n",
"\n",
"left = threading.Thread(target=consume, args=('Left', items.popleft))\n",
"right = threading.Thread(target=consume, args=('Right', items.pop))\n",
"\n",
"left.start()\n",
"right.start()\n",
"\n",
"left.join()\n",
"right.join()\n"
]
}
],
"metadata": {
"interpreter": {
"hash": "9e0fd7424d8281b91a098a189d6ae37333be9d5a00ec75c9d3dec88c73652714"
},
"kernelspec": {
"display_name": "Python 3.10.1 ('leetcode-yPz04C5d')",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.1"
},
"orig_nbformat": 4
},
"nbformat": 4,
"nbformat_minor": 2
}