Skip to content

Instantly share code, notes, and snippets.

@HYChou0515
Last active August 22, 2021 02:38
Show Gist options
  • Save HYChou0515/67b523614a22f4ea9491473576a88c87 to your computer and use it in GitHub Desktop.
Save HYChou0515/67b523614a22f4ea9491473576a88c87 to your computer and use it in GitHub Desktop.

Tasks involving search in a sorted list are pretty common. Sometimes using list literal would be very convenient and fast enough for small list, e.g., [v for v >= x for v in a].

However, when the list is too large, this kind of linear search can cost much time than it is actually needed. Using binary search is preffered in this situation.

Python has a built in library bisect for this kind of job. Sometimes it could be quite confusing how to use, though.

Here I tried to summary the basic usage and some useful application of bisect.

Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "b82362c2",
"metadata": {
"_cell_guid": "b1076dfc-b9ad-4769-8c92-a6c4dae69d19",
"_uuid": "8f2839f25d086af736a60e9eeb907d3b93b6e0e5",
"execution": {
"iopub.execute_input": "2021-08-22T02:26:10.391370Z",
"iopub.status.busy": "2021-08-22T02:26:10.390354Z",
"iopub.status.idle": "2021-08-22T02:26:10.397442Z",
"shell.execute_reply": "2021-08-22T02:26:10.397913Z",
"shell.execute_reply.started": "2021-08-22T02:24:56.966203Z"
},
"papermill": {
"duration": 0.03049,
"end_time": "2021-08-22T02:26:10.398261",
"exception": false,
"start_time": "2021-08-22T02:26:10.367771",
"status": "completed"
},
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"a=[1, 2, 3, 3, 4, 5]\n",
"x=4\n",
"lo=1\n",
"hi=5\n",
"\n",
"###Basic Usage###\n",
"\n",
"Find right most insert index, use bisect_right\n",
"all(v <= x for v in a[lo:i]) for the left side and all(v > x for v in a[i:hi])\n",
"bisect.bisect_right(a, x)=5\n",
"Find left most insert index, use bisect_left\n",
"all(v < x for v in a[lo:i]) for the left side and all(v >= x for v in a[i:hi])\n",
"bisect.bisect_left(a, x)=4\n",
"\n",
"###Application###\n",
"\n",
"[v for v < x for v in a]\n",
"a[:bisect.bisect_left(a, x)]=[1, 2, 3, 3]\n",
"[v for v <= x for v in a]\n",
"a[:bisect.bisect_right(a, x)]=[1, 2, 3, 3, 4]\n",
"[v for v > x for v in a]\n",
"a[bisect.bisect_right(a, x):]=[5]\n",
"[v for v >= x for v in a]\n",
"a[bisect.bisect_left(a, x):]=[4, 5]\n",
"\n",
"[v for v < x for v in a[lo:hi]]\n",
"a[lo:bisect.bisect_left(a, x, lo, hi)]=[2, 3, 3]\n",
"[v for v <= x for v in a[lo:hi]]\n",
"a[lo:bisect.bisect_right(a, x, lo, hi)]=[2, 3, 3, 4]\n",
"[v for v > x for v in a[lo:hi]]\n",
"a[bisect.bisect_right(a, x, lo, hi):hi]=[]\n",
"[v for v >= x for v in a[lo:hi]]\n",
"a[bisect.bisect_left(a, x, lo, hi):hi]=[4]\n"
]
}
],
"source": [
"import bisect\n",
"a = [1,2,3,3,4,5]\n",
"x = 4\n",
"lo=1\n",
"hi=5\n",
"print(f'a={a}')\n",
"print(f'x={x}')\n",
"print(f'lo={lo}')\n",
"print(f'hi={hi}')\n",
"print()\n",
"print('###Basic Usage###')\n",
"print()\n",
"print('Find right most insert index, use bisect_right')\n",
"print('all(v <= x for v in a[lo:i]) for the left side and all(v > x for v in a[i:hi])')\n",
"print(f'bisect.bisect_right(a, x)={bisect.bisect_right(a, x)}')\n",
"print('Find left most insert index, use bisect_left')\n",
"print('all(v < x for v in a[lo:i]) for the left side and all(v >= x for v in a[i:hi])')\n",
"print(f'bisect.bisect_left(a, x)={bisect.bisect_left(a, x)}')\n",
"print()\n",
"print(f'###Application###')\n",
"print()\n",
"print('[v for v < x for v in a]')\n",
"print(f'a[:bisect.bisect_left(a, x)]={a[:bisect.bisect_left(a, x)]}')\n",
"print('[v for v <= x for v in a]')\n",
"print(f'a[:bisect.bisect_right(a, x)]={a[:bisect.bisect_right(a, x)]}')\n",
"print('[v for v > x for v in a]')\n",
"print(f'a[bisect.bisect_right(a, x):]={a[bisect.bisect_right(a, x):]}')\n",
"print('[v for v >= x for v in a]')\n",
"print(f'a[bisect.bisect_left(a, x):]={a[bisect.bisect_left(a, x):]}')\n",
"print()\n",
"print('[v for v < x for v in a[lo:hi]]')\n",
"print(f'a[lo:bisect.bisect_left(a, x, lo, hi)]={a[lo:bisect.bisect_left(a, x, lo, hi)]}')\n",
"print('[v for v <= x for v in a[lo:hi]]')\n",
"print(f'a[lo:bisect.bisect_right(a, x, lo, hi)]={a[lo:bisect.bisect_right(a, x, lo, hi)]}')\n",
"print('[v for v > x for v in a[lo:hi]]')\n",
"print(f'a[bisect.bisect_right(a, x, lo, hi):hi]={a[bisect.bisect_right(a, x, lo, hi):hi]}')\n",
"print('[v for v >= x for v in a[lo:hi]]')\n",
"print(f'a[bisect.bisect_left(a, x, lo, hi):hi]={a[bisect.bisect_left(a, x, lo, hi):hi]}')\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.7.10"
},
"papermill": {
"default_parameters": {},
"duration": 8.63471,
"end_time": "2021-08-22T02:26:11.010100",
"environment_variables": {},
"exception": null,
"input_path": "__notebook__.ipynb",
"output_path": "__notebook__.ipynb",
"parameters": {},
"start_time": "2021-08-22T02:26:02.375390",
"version": "2.3.3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment