diff --git a/事例.ipynb b/事例.ipynb new file mode 100644 index 0000000..41e615e --- /dev/null +++ b/事例.ipynb @@ -0,0 +1,112 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(5, 0)" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "divmod(15,3)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "1+1" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "a = 1+1" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'\\nabc'" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\"\"\"\n", + "abc\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n" + ] + } + ], + "source": [ + "print(input())" + ] + } + ], + "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.11.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/值与相对应运算.ipynb b/值与相对应运算.ipynb new file mode 100644 index 0000000..8793b52 --- /dev/null +++ b/值与相对应运算.ipynb @@ -0,0 +1,769 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 计算机程序两大部分:\n", + "- 运算\n", + "- 流程控制" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "83\n", + "89\n", + "97\n", + "101\n", + "103\n", + "107\n", + "109\n" + ] + } + ], + "source": [ + "def is_prime(n): # 定义 is_prime(),接收一个参数\n", + " if n < 2: # 开始使用接收到的那个参数(值)开始计算……\n", + " return False # 不再是返回给人,而是返回给调用它的代码……\n", + " if n == 2:\n", + " return True\n", + " for m in range(2, int(n**0.5)+1):\n", + " if (n % m) == 0:\n", + " return False\n", + " else:\n", + " return True\n", + "\n", + "for i in range(80, 110):\n", + " if is_prime(i): # 调用 is_prime() 函数,\n", + " print(i) # 如果返回值为 True,则向屏幕输出" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 值\n", + "值是程序的基础步骤
\n", + "运算(Evaluation)\n", + "- 常量(Literal)\n", + "- 变量(Variable)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "8\n" + ] + } + ], + "source": [ + "a = 1 + 2 * 3\n", + "a += 1\n", + "print(a)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 函数值的特殊形式:None\n", + "在 Python 中每个函数都有返回值,即便你在定义一个函数的时候没有设定返回值,它也会加上默认的返回值 None……(请注意 None 的大小写!)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "None\n", + "None\n", + "None\n" + ] + } + ], + "source": [ + "def f():\n", + " pass\n", + "print(f()) # 输出 f() 这个函数被调用后的返回值,None\n", + "print(print(f())) # 这一行最外围的 print() 调用了一次 print(f()),所以输出一个 None,\n", + " # 而后再输出这次调用的返回值,所以又输出一次 None" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "当我们调用一个函数的时候,本质上来看,就相当于:\n", + "\n", + ">我们把一个值交给某个函数,请函数根据它内部的运算和流程控制对其进行操作而后返回另外一个值。\n", + "\n", + "比如,abs() 函数,就会返回传递给它的值的绝对值;int() 函数,会将传递给它的值的小数部分砍掉;float() 接到整数参数之后,会返回这个整数的浮点数形式:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3.14159\n", + "3\n", + "3.0\n" + ] + } + ], + "source": [ + "print(abs(-3.14159))\n", + "print(int(abs(-3.14159)))\n", + "print(float(int(abs(-3.14159))))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 值的类型\n", + "在编程语言中,总是包含最基本的三种数据类型:\n", + "\n", + "- 布尔值(Boolean Value)\n", + "- 数字(Numbers):整数(Int)、浮点数(Float)、复数(Complex Numbers)\n", + "- 字符串(Strings)
\n", + "**运算的一个默认法则就是,通常情况下应该是相同类型的值才能相互运算。**" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "20.0" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "11 + 10 - 9 * 8 / 7 // 6 % 5\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "ename": "TypeError", + "evalue": "can only concatenate str (not \"int\") to str", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[7], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43m3.14\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m+\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m3\u001b[39;49m\n", + "\u001b[1;31mTypeError\u001b[0m: can only concatenate str (not \"int\") to str" + ] + } + ], + "source": [ + "'3.14' + 3" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'33'" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "str(int(float(\"3.14\"))) + str(3)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "所以,在不得不对不同类型的值进行运算之前,总是要事先做 Type Casting(类型转换)。比如:\n", + "\n", + "将字符串转换为数字用 int()、float();
\n", + "将数字转换成字符串用 str();" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "另外,即便是在数字之间进行计算的时候,有时也需要将整数转换成浮点数字,或者反之:\n", + "\n", + "将整数转换成浮点数字用 float();
\n", + "将浮点数字转换成整数用 int();" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "有个函数,type(),可以用来查看某个值属于什么类型:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" + ] + } + ], + "source": [ + "print(type(3))\n", + "print(type(3.0))\n", + "print(type('3.14'))\n", + "print(type(True))\n", + "print(type(range(10)))\n", + "print(type([1,2,3]))\n", + "print(type((1,2,3)))\n", + "print(type({1,2,3}))\n", + "print(type({'a':1, 'b':2, 'c':3}))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 操作符\n", + "|运算符号|含义|\n", + "|-------|----|\n", + "|+|加|\n", + "|-|减|\n", + "|*|乘|\n", + "|**|幂|\n", + "|/|除|\n", + "|//|取商|\n", + "|%|取余|\n", + "# 优先级\n", + "先幂,再乘除,再加减" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 布尔运算优先级\n", + "not > and > or \n" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "False" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "True and False or not True" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 逻辑操作符\n", + "使用范围:数值之间\n", + "# 优先级\n", + "数值运算 > 逻辑操作符 > 布尔值操作符" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "n = -95\n", + "n < 0 and (n + 1) % 2 == 0" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 字符串操作符\n", + "针对字符串,有三种操作:\n", + "\n", + "拼接:+ 和 ' '(后者是空格)
\n", + "拷贝:*
\n", + "逻辑运算:in、not in;以及,<、<=、>、>=、!=、==" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "AwesomePython\n", + "AwesomePython\n", + "Python, Awesome! Awesome! Awesome! \n", + "False\n" + ] + } + ], + "source": [ + "print('Awesome' + 'Python')\n", + "print('Awesome' 'Python')\n", + "print('Python, ' + 'Awesome! ' * 3)\n", + "print('o' in 'Awesome' and 'o' not in 'Python')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 特例:Unicode 码比较" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "'a' < 'b'" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "False\n", + "65\n", + "97\n", + "20320\n" + ] + } + ], + "source": [ + "print('A' > 'a')\n", + "print(ord('A'))\n", + "print(ord('a'))\n", + "print(ord(\"你\"))" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "False" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "'PYTHON' > 'Python 3'" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "你好\n" + ] + } + ], + "source": [ + "print(\"python\" and \"你好\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 列表操作符\n", + "因为列表和字符串一样,都是有序容器(容器还有另外一种是无序容器),所以,它们可用的操作符其实相同:\n", + "\n", + "拼接:+ 和 ' '(后者是空格)
\n", + "拷贝:*
\n", + "逻辑运算:in、not in;以及,<、<=、>、>=、!=、==
\n", + "\n", + "两个列表在比较时(前提是两个列表中的数据元素类型相同),遵循的还是跟字符串比较相同的规则:“一旦决出胜负马上停止”。
\n", + "类型不同比较会报错!" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "False" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from IPython.core.interactiveshell import InteractiveShell\n", + "InteractiveShell.ast_node_interactivity = \"all\"\n", + "\n", + "a_list = [1, 2, 3, 4, 5]\n", + "b_list = [1, 2, 3, 5]\n", + "c_list = ['ann', 'bob', 'cindy', 'dude', 'eric']\n", + "a_list > b_list\n", + "10 not in a_list\n", + "'ann' in c_list" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 关于布尔值的一些补充" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "True or \"python\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`False`定义为空\n", + "那么`True`的定义便是有" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 关于值类型的一些补充" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "除了数字、布尔值、字符串,以及上一小节介绍的列表之外,还有若干数据类型,比如 `range()`(等差数列)、`tuple`(元组)、`set`(集合)、`dictionary`(字典),再比如 `Date Type`(日期)等等。\n", + "\n", + "它们都是基础数据类型的各种组合 —— 现实生活中,更多需要的是把基础类型组合起来构成的数据。比如,一个通讯簿,里面是一系列字符串分别对应着若干字符串和数字。\n", + "\n", + "``` python\n", + "entry[3662] = {\n", + " 'first_name': 'Michael',\n", + " 'last_name': 'Willington',\n", + " 'birth_day': '12/07/1992',\n", + " 'mobile': {\n", + " '+714612234', \n", + " '+716253923'\n", + " }\n", + " 'id': 3662,\n", + " ...\n", + "}\n", + "``` \n", + "\n", + "针对不同的类型,都有相对应的操作符,可以对其进行运算。\n", + "\n", + "这些类型之间有时也有不得不相互运算的需求,于是,在相互运算之前同样要 _Type Casting_,比如将 List 转换为 Set,或者反之:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n", + "1\n", + "2\n", + "3\n", + "4\n", + "5\n", + "6\n", + "7\n", + "8\n", + "9\n" + ] + } + ], + "source": [ + "for i in range(10):\n", + " print(i)" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "('你好', '我不好')\n", + "1\n" + ] + } + ], + "source": [ + "a = (\"你好\",\"我不好\")\n", + "print(a)\n", + "a = 1\n", + "print(a)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'我不好'" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\"你好\" and \"我不好\"" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'小明': 5, '小红': 3}\n" + ] + } + ], + "source": [ + "dic = {\"小明\":5,\"小红\":3}\n", + "print(dic)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "[1, 2, 3, 4, 5, 6, 7]" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "{1, 2, 3, 4, 5, 6, 7}" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "[1, 2, 3, 4, 5, 6, 7]" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from IPython.core.interactiveshell import InteractiveShell\n", + "InteractiveShell.ast_node_interactivity = \"all\"\n", + "\n", + "a = [1, 2, 3, 4, 5, 6, 7] #数组Array #列表\n", + "print(type(a))\n", + "b = set(a)\n", + "c = list(b)\n", + "a\n", + "b\n", + "c" + ] + } + ], + "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.11.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/入口.ipynb b/入口.ipynb new file mode 100644 index 0000000..3ef6050 --- /dev/null +++ b/入口.ipynb @@ -0,0 +1,691 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**程序**是按照一定**顺序**完成任务的流程\n", + "\n", + "做蛋炒饭步骤:\n", + "- 准备米饭\n", + "- 准备鸡蛋\n", + "- 准备配料\n", + "- 炒蛋\n", + "- 炒配料\n", + "- 调味\n", + "- 出锅\n", + "\n", + "菜谱 = 程序 -- 自然语言 -->程序语言\n", + "编写者 是人\n", + "执行者 是人ß\n", + "\n", + "计算机程序和人做饭程序最关键差别是**布尔运算**\n", + "- 按照顺序执行任务\n", + "- 根据不同情况执行不同任务\n", + " ~ 如果条件满足,则重复执行某一任务\n", + "\n", + "计算机强大便是在于他**可编程**\n", + "而可编程的核心在于**布尔运算**及其相应**流程控制**\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "False\n", + "True\n" + ] + } + ], + "source": [ + "print(1 == 2)\n", + "print(1 != 2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "vscode": { + "languageId": "html" + } + }, + "source": [ + "# 逻辑运算符\n", + "| 比较操作符 | 意义 | 示例 | 布尔值 | \n", + "| --- | --- | --- | --- | \n", + "| == | 等于 | 1 == 2 | False | \n", + "| != | 不等于 | 1 != 2 | True | \n", + "| > | 大于 | 1 >2 | False | \n", + "| >= | 大于等于 | 1>= 1 | True | \n", + "| < | 小于 | 1< 2 | True | \n", + "| <= | 小于等于 | 1<=2 | True | \n", + "| in | 属于 | \"a\" in \"basic\" | True | " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 布尔运算操作符\n", + "操作对象:数字值或字符串值\n", + "操作运算符:与、或、非\n", + "| and | True | False |\n", + "|--------|--------|---------|\n", + "| True | True | False | \n", + "| False | False | False | \n", + "\n", + "
\n", + "\n", + "| or | True | False |\n", + "|--------|--------|---------|\n", + "| True | True | True | \n", + "| False | True | False | \n", + "\n", + "
\n", + "\n", + "| not | True | False |\n", + "|--------|--------|---------|\n", + "| | False | True | " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(True and False) yields: False\n", + "(True and True) yields: True\n", + "(False and True) yields: False\n", + "(True or False) yields: True\n", + "(False or True) yields: True\n", + "(False or False) yields: False\n", + "(not True) yields: False\n", + "(not False) yields: True\n" + ] + } + ], + "source": [ + "print('(True and False) yields:', True and False)\n", + "print('(True and True) yields:', True and True)\n", + "print('(False and True) yields:', False and True)\n", + "print('(True or False) yields:', True or False)\n", + "print('(False or True) yields:', False or True)\n", + "print('(False or False) yields:', False or False)\n", + "print('(not True) yields:', not True)\n", + "print('(not False) yields:', not False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 流程控制" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "255 is odd.\n" + ] + } + ], + "source": [ + "import random\n", + "r = random.randrange(1, 1000)\n", + "# 暂时忽略以上两句的原理,只需要了解其结果:\n", + "# 引入随机数,而后,每次执行的时候,r 的值不同\n", + "\n", + "if r % 2 == 0:\n", + " print(r, 'is even.')\n", + "else:\n", + " print(r, 'is odd.')" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "1+1" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2\n" + ] + } + ], + "source": [ + "print(1+1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "|英文|中文|\n", + "|---|---|\n", + "|Assignment|赋值|\n", + "|Variable|变量|\n", + "|Literal|常量|\n", + "|Loop|循环|" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n", + "3\n", + "5\n", + "7\n", + "9\n" + ] + } + ], + "source": [ + "for i in range(10):\n", + " if i % 2 != 0:\n", + " print(i)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "打印100以为的质数
\n", + "质数定义:一个数,大于等于2,且只有在被它自身或者1做为除数时余数为0
\n", + "设n为整数,n>=2;
\n", + "若n==2,n是质数;
\n", + "若n>2,就把n作为被除数,从2开始一直到n-1都作为除数,逐一计算看看余数是否等于0?
\n", + "    如果是,那就不用接着算了,它不是质数;
\n", + "    如果全部都试过了,余数都不是0,那么它是质数。
" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2\n", + "3\n", + "5\n", + "7\n", + "11\n", + "13\n", + "17\n", + "19\n", + "23\n", + "29\n", + "31\n", + "37\n", + "41\n", + "43\n", + "47\n", + "53\n", + "59\n", + "61\n", + "67\n", + "71\n", + "73\n", + "79\n", + "83\n", + "89\n", + "97\n" + ] + } + ], + "source": [ + "for n in range(2, 100): #range(2,100)表示含左侧 2,不含右侧 100,是不是第三次看到这个说法了?\n", + " if n == 2:\n", + " print(n)\n", + " continue\n", + " for i in range(2, n):\n", + " if (n % i) == 0:\n", + " break\n", + " else: # 这里目前你可能看不懂…… 但先关注结果吧。\n", + " print(n) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 算法\n", + "以上程序,都可以称之为算法,而以上算法也都可以优化。\n", + "比方说寻找质数的时候,完全没有必要将终点设在99,按照数学逻辑,设置在√n就好\n", + "```python\n", + "for n in range(2, 100):\n", + " if n == 2:\n", + " print(n)\n", + " continue\n", + " for i in range(2, int(n ** 0.5)+1): #为什么要 +1 以后再说…… n 的 1/2 次方,相当于根号 n。\n", + " if (n % i) == 0:\n", + " break\n", + " else:\n", + " print(n) \n", + "\n", + "优化没有固定的方法,所有工具,其效率都取决于使用他的人" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 函数\n", + "- 函数名(Function Name)\n", + "- 参数(Parameters)\n", + "- 返回值(Return Value)\n", + "- 调用(Call)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "3.1415926" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "a = abs(-3.1415926)\n", + "a" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "pip install xxx" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def is_prime(n): # 定义 is_prime(),接收一个参数\n", + " if n < 2: # 开始使用接收到的那个参数(值)开始计算……\n", + " return False # 不再是返回给人,而是返回给调用它的代码……\n", + " if n == 2:\n", + " return True\n", + " for m in range(2, int(n**0.5)+1):\n", + " if (n % m) == 0:\n", + " return False\n", + " else:\n", + " return True\n", + "\n", + "for i in range(80, 110):\n", + " if is_prime(i): # 调用 is_prime() 函数,\n", + " print(i) # 如果返回值为 True,则向屏幕输出 i" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 细节补充,整体概括" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 语句" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n", + "3\n", + "5\n", + "7\n", + "9\n", + "----------------------------------\n", + "1\n", + "3\n", + "5\n", + "7\n", + "9\n" + ] + } + ], + "source": [ + "# 通常情况下,建议一行写一条语句\n", + "for i in range(10):\n", + " if i % 2 != 0:\n", + " print(i)\n", + "\n", + "print(\"----------------------------------\")\n", + "\n", + "#但是,有时为了简化,也会使用一行表达\n", + "print(\"\\n\".join(str(i) for i in range(10) if i % 2 != 0))\n", + "\n", + "#但是,要注意,这样子写虽然逼格上来了,但是对计算机来说,效率没有上面高" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 语句块" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n", + "3\n", + "5\n", + "7\n", + "9\n", + "11\n", + "13\n", + "15\n", + "17\n", + "19\n", + "Collected odd numbers: [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]\n" + ] + } + ], + "source": [ + "def collect_and_print_odd_numbers(n):\n", + " # 初始化一个空列表来存储奇数\n", + " odd_numbers = []\n", + "\n", + " # 循环从0到n(包括n)\n", + " for i in range(n + 1):\n", + " if i % 2 != 0:\n", + " # 如果i是奇数,则将其添加到列表中\n", + " odd_numbers.append(i)\n", + " \n", + " # 打印奇数列表中的每个数字\n", + " print(\"\\n\".join(str(num) for num in odd_numbers))\n", + "\n", + " # 返回奇数列表\n", + " return odd_numbers\n", + "\n", + "# 调用函数,收集并打印0到20之间的奇数\n", + "odd_numbers_list = collect_and_print_odd_numbers(20)\n", + "print(\"Collected odd numbers:\", odd_numbers_list)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#python的注释一共有两种方法\n", + "#一般来说,这种写法放在中间\n", + "\n", + "\"\"\"\n", + "三个引号中间,都是注释区域\n", + "\n", + "一般来说,这种注释方法写在开头\n", + "\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\"\"\"\n", + "\n", + "\"\"\"\n", + "#" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n" + ] + } + ], + "source": [ + "你好 = 1\n", + "print(你好)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n", + "3\n", + "5\n", + "7\n", + "9\n", + "11\n", + "13\n", + "15\n", + "17\n", + "19\n", + "Collected odd numbers: [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]\n" + ] + } + ], + "source": [ + "def collect_and_print_odd_numbers(n):\n", + "\n", + " \"\"\"\n", + " 打印并返回从0到给定数字n之间的所有奇数。\n", + "\n", + " 参数:\n", + " n (int): 要检查的最大数字。\n", + "\n", + " 返回:\n", + " list: 包含所有奇数的列表。\n", + " \"\"\"\n", + " \n", + " # 初始化一个空列表来存储奇数\n", + " odd_numbers = []\n", + "\n", + " # 循环从0到n(包括n)\n", + " for i in range(n + 1):\n", + " if i % 2 != 0:\n", + " # 如果i是奇数,则将其添加到列表中\n", + " odd_numbers.append(i)\n", + " \n", + " # 打印奇数列表中的每个数字\n", + " print(\"\\n\".join(str(num) for num in odd_numbers))\n", + "\n", + " # 返回奇数列表\n", + " return odd_numbers\n", + "\n", + "# 调用函数,收集并打印0到20之间的奇数\n", + "odd_numbers_list = collect_and_print_odd_numbers(20)\n", + "print(\"Collected odd numbers:\", odd_numbers_list)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 操作运算符" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "|运算符号|含义|\n", + "|-------|----|\n", + "|+|加|\n", + "|-|减|\n", + "|*|乘|\n", + "|**|幂|\n", + "|/|除|\n", + "|//|取商|\n", + "|%|取余|" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# 加法示例\n", + "a = 5\n", + "b = 3\n", + "sum_result = a + b # 5 + 3 = 8\n", + "print(\"加法结果:\", sum_result)\n", + "\n", + "# 减法示例\n", + "sub_result = a - b # 5 - 3 = 2\n", + "print(\"减法结果:\", sub_result)\n", + "\n", + "# 乘法示例\n", + "mul_result = a * b # 5 * 3 = 15\n", + "print(\"乘法结果:\", mul_result)\n", + "\n", + "# 除法示例\n", + "div_result = a / b # 5 / 3 = 1.6666666666666667\n", + "print(\"除法结果:\", div_result)\n", + "\n", + "# 幂运算示例\n", + "pow_result = a ** b # 5 ** 3 = 125\n", + "print(\"幂运算结果:\", pow_result)\n", + "\n", + "# 取商示例\n", + "floordiv_result = a // b # 5 // 3 = 1\n", + "print(\"取商结果:\", floordiv_result)\n", + "\n", + "# 取余示例\n", + "mod_result = a % b # 5 % 3 = 2\n", + "print(\"取余结果:\", mod_result)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 赋值" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3\n", + "2\n" + ] + } + ], + "source": [ + "a = 1\n", + "a = a + 1\n", + "a += 1\n", + "print(a)\n", + "a = 2\n", + "print(a)" + ] + } + ], + "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.11.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/字符串.ipynb b/字符串.ipynb new file mode 100644 index 0000000..53a4f37 --- /dev/null +++ b/字符串.ipynb @@ -0,0 +1,2511 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "toc-hr-collapsed": false + }, + "source": [ + "# 字符串" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "在计算机里,所有的东西最终都要被转换成数值。又由于计算机靠的是电路,所以,最终只能处理 `1` 和 `0`,于是,最基本的数值是二进制;于是,连整数、浮点数字,都要最终转换成二进制数值。这就是为什么在所有编程语言中 `1.1 + 2.2` 并不是你所想象的 `3.3` 的原因。" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "3.3000000000000003" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "1.1 + 2.2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "因为最终所有的值都要转换成二进制 —— 这时候,小数的精度就有损耗,多次浮点数字转换成二进制相互运算之后再从二进制转换为十进制之后返回的结果,精度损耗就更大了。因此,在计算机上,浮点数字的精度总有极限。\n", + "\n", + "字符串也一样。一个字符串由 0 个字符或者多个字符构成,它最终也要被转换成数值,再进一步被转换成二进制数值。空字符串的值是 `None`,即便是这个 `None` —— 也最终还是要被转换成二进制的 `0`。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 字符码表的转换" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "把**单个字符**转换成码值的函数是 `ord()`,它只接收单个字符,否则会报错;它返回该字符的 unicode 编码。与 `ord()` 相对的函数是 `chr()`,它接收且只接收一个整数作为参数,而后返回相应的字符。" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "97" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "'z'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "27653" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "'挊'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from IPython.core.interactiveshell import InteractiveShell\n", + "InteractiveShell.ast_node_interactivity = \"all\"\n", + "\n", + "ord('a')\n", + "chr(122)\n", + "\n", + "ord('氅')\n", + "chr(25354)\n", + "\n", + "# ord('Python') # 这一句会报错" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "## 字符串的标示" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "标示一个字符串,有 4 种方式,用单引号、用双引号,用三个单引号或者三个双引号:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Simple is better than complex.'" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "'Simple is better than complex.' # 用单引号" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Simple is better than complex.'" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\"Simple is better than complex.\" # 用双引号" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'\\nSimple is better than complex.\\nComplex is better than complicated.\\n'" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# 用三个单引号。注意输出结果中的 \\n\n", + "# 这个字符串,看起来是两行,保存在内存或者变量之中的时候,\n", + "# 是一整串,其中的换行是用 \\n 表示的。\n", + "'''\n", + "Simple is better than complex.\n", + "Complex is better than complicated.\n", + "''' " + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'\\nSimple is better than complex.\\nComplex is better than complicated.\\n'" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#用三个双引号。注意输出结果中的 \\n\n", + "\"\"\"\n", + "Simple is better than complex.\n", + "Complex is better than complicated.\n", + "\"\"\" " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Simple is better than complex.\n", + "Complex is better than complicated.\n", + "\n" + ] + } + ], + "source": [ + "print(\n", + "\"\"\"\n", + "Simple is better than complex.\n", + "Complex is better than complicated.\n", + "\"\"\"\n", + ") #用 print() 输出的时候,\\n 就是不可见字符,字符串本身如下:\n", + "# '\\nSimple is better than complex.\\nComplex is better than complicated.\\n'\n", + "# 其中的 \\n 被打印出来的时候显示成换行" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "toc-hr-collapsed": true + }, + "source": [ + "## 字符串与数值之间的转换" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "由数字构成的字符串,可以被转换成数值,转换整数用 `int()`,转换浮点数字用 `float()`。\n", + "\n", + "与之相对,用 `str()`,可以将数值转换成字符串类型。\n", + "\n", + "注意,int() 在接收字符串为参数的时候,只能做整数转换。下面代码最后一行会报错:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "3" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "3.0" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "'3.1415926'" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from IPython.core.interactiveshell import InteractiveShell\n", + "InteractiveShell.ast_node_interactivity = \"all\"\n", + "\n", + "int('3')\n", + "float('3')\n", + "str(3.1415926)\n", + "# int('3.1415926') # 这一行会报错" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`input()` 这个内建函数的功能是接收用户的键盘输入,而后将其作为字符串返回。它可以接收一个字符串作为参数,在接收用户键盘输入之前,会把这个参数输出到屏幕,作为给用户的提示语。这个参数是可选参数,直接写 `input()`,即,没有提供参数,那么它在要求用户输入的时候,就没有提示语。\n", + "\n", + "以下代码会报错,因为 `age < 18` 不是合法的逻辑表达式,因为 `age` 是由 `input()` 传递过来的字符串;于是,它不是数字,那么它不可以与数字比较……" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Please tell me your age: 19\n" + ] + }, + { + "ename": "TypeError", + "evalue": "'<' not supported between instances of 'str' and 'int'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mage\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0minput\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Please tell me your age: '\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0mage\u001b[0m \u001b[0;34m<\u001b[0m \u001b[0;36m18\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'I can not sell you drinks...'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Have a nice drink!'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mTypeError\u001b[0m: '<' not supported between instances of 'str' and 'int'" + ] + } + ], + "source": [ + "age = input('Please tell me your age: ')\n", + "if age < 18:\n", + " print('I can not sell you drinks...')\n", + "else:\n", + " print('Have a nice drink!')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "要改成这样才可能行:\n", + "为什么是可能行而不是一定行?如果用户 `input` 键盘输入的是 `eighteen` 或者 ` 十八 ` 等,依然会导致 `int()` 失败并得到 `ValueError` 的报错。用户输入的不可控,可能会导致千奇百怪的报错。但在这里,我们先简化处理,在引导语中加入一个正确的示例并默认用户会按引导语正确输入。" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "ename": "KeyboardInterrupt", + "evalue": "Interrupted by user", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[4], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m age \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mint\u001b[39m(\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m'''\u001b[39;49m\u001b[38;5;124;43mPlease tell me your age: \u001b[39;49m\n\u001b[0;32m 2\u001b[0m \u001b[38;5;124;43m an int number , e.g: 22\u001b[39;49m\n\u001b[0;32m 3\u001b[0m \u001b[38;5;124;43m'''\u001b[39;49m\u001b[43m)\u001b[49m)\n\u001b[0;32m 4\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m age \u001b[38;5;241m<\u001b[39m \u001b[38;5;241m18\u001b[39m:\n\u001b[0;32m 5\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mI can not sell you drinks...\u001b[39m\u001b[38;5;124m'\u001b[39m)\n", + "File \u001b[1;32m~\\AppData\\Roaming\\Python\\Python311\\site-packages\\ipykernel\\kernelbase.py:1270\u001b[0m, in \u001b[0;36mKernel.raw_input\u001b[1;34m(self, prompt)\u001b[0m\n\u001b[0;32m 1268\u001b[0m msg \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mraw_input was called, but this frontend does not support input requests.\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 1269\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m StdinNotImplementedError(msg)\n\u001b[1;32m-> 1270\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_input_request\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 1271\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mstr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mprompt\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 1272\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_parent_ident\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mshell\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 1273\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_parent\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mshell\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 1274\u001b[0m \u001b[43m \u001b[49m\u001b[43mpassword\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[0;32m 1275\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32m~\\AppData\\Roaming\\Python\\Python311\\site-packages\\ipykernel\\kernelbase.py:1313\u001b[0m, in \u001b[0;36mKernel._input_request\u001b[1;34m(self, prompt, ident, parent, password)\u001b[0m\n\u001b[0;32m 1310\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mKeyboardInterrupt\u001b[39;00m:\n\u001b[0;32m 1311\u001b[0m \u001b[38;5;66;03m# re-raise KeyboardInterrupt, to truncate traceback\u001b[39;00m\n\u001b[0;32m 1312\u001b[0m msg \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mInterrupted by user\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m-> 1313\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mKeyboardInterrupt\u001b[39;00m(msg) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m 1314\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m:\n\u001b[0;32m 1315\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mlog\u001b[38;5;241m.\u001b[39mwarning(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mInvalid Message:\u001b[39m\u001b[38;5;124m\"\u001b[39m, exc_info\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m)\n", + "\u001b[1;31mKeyboardInterrupt\u001b[0m: Interrupted by user" + ] + } + ], + "source": [ + "age = int(input('''Please tell me your age: \n", + " an int number , e.g: 22\n", + "'''))\n", + "if age < 18:\n", + " print('I can not sell you drinks...')\n", + "else:\n", + " print('Have a nice drink!')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 转义符" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "有一个重要的字符,叫做 “转义符”,`\\`,也有的地方把它称为 “脱字符”,因为它的英文原文是 _Escaping Character_。它本身不被当作字符,你要想在字符串里含有这个字符,得这样写 `\\\\`:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'\\\\'" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "'\\\\'" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "ename": "SyntaxError", + "evalue": "EOL while scanning string literal (, line 1)", + "output_type": "error", + "traceback": [ + "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m '\\'\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m EOL while scanning string literal\n" + ] + } + ], + "source": [ + "'\\'" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "如果你想输出这么个字符串,`He said, it's fine.`,如果用双引号扩起来 `\"` 倒没啥问题,但是如果用单引号扩起来就麻烦了,因为编译器会把 `it` 后面的那个单引号 `'` 当作字符串结尾。" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "ename": "SyntaxError", + "evalue": "invalid syntax (, line 1)", + "output_type": "error", + "traceback": [ + "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m 'He said, it's fine.'\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" + ] + } + ], + "source": [ + "'He said, it's fine.'" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "于是你就得用转义符 `\\`:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\"He said, it's fine.\"" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "\"He said, it's fine.\"" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "\"He said, it's fine.\"" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from IPython.core.interactiveshell import InteractiveShell\n", + "InteractiveShell.ast_node_interactivity = \"all\"\n", + "\n", + "# 要么你这么写:\n", + "'He said, it\\'s fine.'\n", + "# 要么你这么写:\n", + "\"He said, it's fine.\"\n", + "# 要么,不管用单引号还是双引号标示字符串,都习惯于用 \\' 和 \\\" 书写属于字符串内部的引号……\n", + "\"He said, it\\'s fine.\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "转义符号 `\\` 的另外两个常用形式是和 `t`、`n` 连起来用,`\\t` 代表制表符(就是用 TAB `⇥` 键敲出来的东西),`\\n` 代表换行符(就是用 Enter `⏎` 敲出来的东西)。\n", + "\n", + "所以,一个字符串,有两种形式,**raw** 和 **presentation**,在后者中,`\\t` 被转换成制表符,`\\n` 被转换成换行。\n", + "\n", + "在写程序的过程中,我们在代码中写的是 _raw_,而例如当我们调用 `print()` 将字符串输出到屏幕上时,是 _presentation_:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "He said, it's fine.\n" + ] + } + ], + "source": [ + "s = \"He said, it\\'s fine.\" # raw\n", + "print(s) # presentation" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "## 字符串的操作符" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "字符串可以用空格 `' '` 或者 `+` 拼接:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Hey! You!'" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "'Hey!' + ' ' + 'You!' # 使用操作符 +" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Hey!You!'" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "'Hey!' 'You!' # 空格与 + 的作用是相同的。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "字符串还可以与整数倍操作符 `*` 操作,`'Ha' * 3` 的意思是说,把字符串 `'Ha'` 复制三遍:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'HaHaHa'" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "'Ha' * 3" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'3.143.143.14'" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "'3.14' * 3" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "字符串还可以用 `in` 和 `not in` 操作符 —— 看看某个字符或者字符串是否被包含在某个字符串中,返回的是布尔值:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "'o' in 'Hey, You!'" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 字符串的索引" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "字符串是由一系列的字符构成的。在 Python 当中,有一个容器(Container)的概念,这个概念前面提到过,后面还会深入讲解。现在需要知道的是,字符串是容器的一种;容器可分为两种,有序的和无序的 —— 字符串属于**有序容器**。\n", + "\n", + "字符串里的每个字符,对应着一个从 `0` 开始的索引。比较有趣的是,索引可以是负数:\n", + "\n", + "\n", + "| 0 | 1 | 2 | 3 | 4 | 5 |\n", + "| ---- | ---- | ---- | ---- | ---- | ---- |\n", + "| P | y | t | h | o | n |\n", + "| -6 | -5 | -4 | -3 | -2 | -1 |" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 P\n", + "1 y\n", + "2 t\n", + "3 h\n", + "4 o\n", + "5 n\n" + ] + } + ], + "source": [ + "s = 'Python'\n", + "for char in s:\n", + " print(s.index(char), char)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "对于有序容器中的元素 —— 字符串就是字符的有序容器 —— 由于它们是有索引的,所以我们可以根据索引提取容器中的值,你可以把 `[]` 当作是有序容器的操作符之一,我们姑且将其称为 “*索引操作符*”。注意以下代码第 3 行中,`s` 后面的 `[]`,以及里面的变量 `i`:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "P\n", + "y\n", + "t\n", + "h\n", + "o\n", + "n\n" + ] + } + ], + "source": [ + "s = 'Python'\n", + "for i in range(len(s)):\n", + " print(s[i])\n", + "\n", + "#上面的代码仅是为了演示索引操作符的使用,更简洁的写法是:\n", + "for i in s:\n", + " print(i)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "我们可以使用*索引操作符*根据*索引**提取**字符串这个*有序容器*中的*一个或多个元素,即,其中的字符或字符串。这个 “提取” 的动作有个专门的术语,叫做 “Slicing”(切片)。索引操作符 `[]` 中可以有一个、两个或者三个整数参数,如果有两个参数,需要用 `:` 隔开。它最终可以写成以下 4 种形式:\n", + "\n", + "> * `s[index]` —— 返回索引值为 `index` 的那个字符\n", + "> * `s[start:]` —— 返回从索引值为 `start` 开始一直到字符串末尾的所有字符\n", + "> * `s[start:stop]` —— 返回从索引值为 `start` 开始一直到索引值为 `stop` 的那个字符*之前*的所有字符\n", + "> * `s[:stop]` —— 返回从字符串开头一直到索引值为 `stop` 的那个字符*之前*的所有字符\n", + "> * `s[start:stop:step]` —— 返回从索引值为 `start` 开始一直到索引值为 `stop` 的那个字符*之前*的,以 `step` 为步长提取的所有字符" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'y'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "'thon'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "'tho'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "'Pytho'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "'yh'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from IPython.core.interactiveshell import InteractiveShell\n", + "InteractiveShell.ast_node_interactivity = \"all\"\n", + "\n", + "s = 'Python'\n", + "s[1]\n", + "s[2:]\n", + "s[2:5]\n", + "s[:5]\n", + "s[1:5:2]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "## 处理字符串的内建函数" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "[Python 内建函数](https://docs.python.org/3/library/functions.html#slice)中,把字符串当做处理对象的有:`ord()`、`input()`、`int()`、`float()`、`len()`、`print()`。再次注意,`ord()` 只接收单个字符为参数。" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "9" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "13" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "'A'" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "请照抄一遍这个数字 3.14: 3.14\n" + ] + }, + { + "data": { + "text/plain": [ + "3" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "28.26" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "4" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3.143.143.14\n" + ] + } + ], + "source": [ + "from IPython.core.interactiveshell import InteractiveShell\n", + "InteractiveShell.ast_node_interactivity = \"all\"\n", + "\n", + "ord('\\n')\n", + "ord('\\t')\n", + "ord('\\r')\n", + "chr(65) # 与 ord() 相对的函数\n", + "s = input('请照抄一遍这个数字 3.14: ')\n", + "int('3')\n", + "# int(s) 这一句会报错…… 所以暂时注释掉了\n", + "float(s) * 9\n", + "len(s)\n", + "print(s*3)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + }, + "toc-hr-collapsed": true + }, + "source": [ + "## 处理字符串的 Method" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "在 Python 中,字符串是一个**对象** —— 更准确地讲,是 str 类(`Class str`)的对象。\n", + "\n", + "调用 str 类的 Methods 是使用 `.` 这个符号,比如:\n", + "\n", + "```python\n", + "'Python'.upper()\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + }, + "toc-hr-collapsed": false + }, + "source": [ + "### 大小写转换" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "转换字符串大小写的是 `str.upper()`、`str.lower()`;另外,还有专门针对行首字母大写的 `str.capitalize()` 和针对每个词的首字母大写的 `str.title()`:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'NOW IS BETTER THAN NEVER.'" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "'now is better than never.'" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from IPython.core.interactiveshell import InteractiveShell\n", + "InteractiveShell.ast_node_interactivity = \"all\"\n", + "\n", + "'Now is better than never.'.upper()\n", + "\n", + "'Now is better than never.'.lower()" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Now is better than never.'" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "'Now Is Better Than Never.'" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from IPython.core.interactiveshell import InteractiveShell\n", + "InteractiveShell.ast_node_interactivity = \"all\"\n", + "\n", + "s = 'Now is better than never.'\n", + "s.capitalize() # 句首字母大写\n", + "s.title() # 每个单词首字母大写" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'nOW IS BETTER THAN NEVER.'" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "'Now Is Better Than Never.'" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "'nOW iS bETTER tHAN nEVER.'" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "s = 'Now is better than never.'\n", + "s.swapcase() # 逐个字符更替大小写\n", + "s.title() \n", + "s.title().swapcase() " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "另外,还有个 `str.encode()` 在处理非英文字符串(比如中文)的时候,经常会用到:" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "b'\\xe7\\xae\\x80\\xe5\\x8d\\x95\\xe4\\xbc\\x98\\xe4\\xba\\x8e\\xe5\\xa4\\x8d\\xe6\\x9d\\x82\\xe3\\x80\\x82'" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# str.encode(encoding=\"utf-8\", errors=\"strict\")\n", + "# 关于更多可能的 encoding list, 请参阅:\n", + "# https://docs.python.org/3/library/codecs.html#standard-encodings\n", + "s = '简单优于复杂。'\n", + "s.encode()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "### 搜索与替换" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "让我们从 `str.count()` 这个搜寻子字符串出现次数的 Method(即,`str` 这个 `Class` 中定义的函数)开始。\n", + "\n", + "官方文档是这么写的:\n", + "\n", + "> `str.count(sub[,start[,end]])`\n", + "\n", + "下面的函数说明加了默认值,以便初次阅读更容易理解:\n", + "\n", + "> `str.count(sub [,start=0[, end=len(str)]])`\n", + "\n", + "这里的方括号 `[]` 表示该参数可选;方括号里再次嵌套了一个方括号,这个意思是说,在这个可选参数 `start` 出现的情况下,还可以再有一个可选参数 `end`;\n", + "\n", + "而 `=` 表示该参数有个默认值。\n", + "\n", + "> * 只给定 `sub` 一个参数的话,于是从第一个字符开始搜索到字符串结束;\n", + "> * 如果,随后给定了一个可选参数的话,那么它是 `start`,于是从 `start` 开始,搜索到字符串结束;\n", + "> * 如果 `start` 之后还有参数的话,那么它是 `end`;于是从 `start` 开始,搜索到 `end - 1` 结束(即不包含索引值为 `end` 的那个字符)。\n", + "> \n", + "> 返回值为字符串中 `sub` 出现的次数。\n", + "\n", + "注意:字符串中第一个字符的索引值是 `0`。\n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "4" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "' '" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "3" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "1" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from IPython.core.interactiveshell import InteractiveShell\n", + "InteractiveShell.ast_node_interactivity = \"all\"\n", + "\n", + "s = \"\"\"Simple is better than complex.\n", + "Complex is better than complicated.\"\"\"\n", + "s.lower().count('mp')\n", + "s[6]\n", + "s.lower().count('mp', 10)\n", + "s.lower().count('mp', 10, 30)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "以下是 `str` 的搜索与替换的 Methods:`str.find()`, `str.rfind()`, `str.index()` 的示例:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Example of str.find():\n" + ] + }, + { + "data": { + "text/plain": [ + "2" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "24" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "-1" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Example of str.rfind():\n" + ] + }, + { + "data": { + "text/plain": [ + "56" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "56" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "-1" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Example of str.index():\n" + ] + }, + { + "data": { + "text/plain": [ + "2" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "56" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n" + ] + } + ], + "source": [ + "from IPython.core.interactiveshell import InteractiveShell\n", + "InteractiveShell.ast_node_interactivity = \"all\"\n", + "\n", + "# str.find(sub[, start[, end]])\n", + "print('Example of str.find():')\n", + "s = \"\"\"Simple is better than complex.\n", + "Complex is better than complicated.\"\"\"\n", + "s.lower().find('mpl')\n", + "s.lower().find('mpl', 10)\n", + "s.lower().find('mpl', 10, 20) # 没有找到就返回 -1\n", + "print()\n", + "\n", + "print('Example of str.rfind():')\n", + "# str.rfind(sub[, start[, end]])\n", + "# rfind() 返回最后 sub 出现的那次的位置;find()是最早的那次\n", + "s.lower().rfind('mpl')\n", + "s.lower().rfind('mpl', 10)\n", + "s.lower().rfind('mpl', 10, 20) # 没有找到就返回 -1\n", + "print()\n", + "\n", + "print('Example of str.index():')\n", + "# str.index(sub[, start[, end]])\n", + "# 作用与 find() 相同,但如果没找到的话,会触发 ValueError 异常\n", + "# https://docs.python.org/3/library/exceptions.html#ValueError\n", + "s.lower().index('mpl')\n", + "# str.rindex(sub[, start[, end]])\n", + "# 作用与 rfind() 相同,但如果没找到的话,会触发 ValueError 异常\n", + "s.lower().rindex('mpl')\n", + "print()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`str.startswith()` 和 `str.endswith()` 是用来判断一个*字符串*是否以某个*子字符串*起始或者结束的:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "s.lower().startswith('S'): False\n", + "s.lower().startswith('b', 10): True\n", + "s.lower().startswith('e', 11, 20): True\n", + "s.lower().endswith('.'): True\n", + "s.lower().endswith('.', 10): True\n", + "s.lower().endswith('.', 10, 20): False\n", + "s.lower().startswith('S'): False\n" + ] + } + ], + "source": [ + "s = \"\"\"Simple is better than complex.\n", + "Complex is better than complicated.\"\"\"\n", + "\n", + "# str.startswith(prefix[, start[, end]])\n", + "print(\"s.lower().startswith('S'):\", \\\n", + " s.lower().startswith('S'))\n", + "print(\"s.lower().startswith('b', 10):\", \\\n", + " s.lower().startswith('b', 10))\n", + "print(\"s.lower().startswith('e', 11, 20):\", \\\n", + " s.lower().startswith('e', 11, 20))\n", + "\n", + "# str.endswith(suffix[, start[, end]])\n", + "print(\"s.lower().endswith('.'):\", \\\n", + " s.lower().endswith('.'))\n", + "print(\"s.lower().endswith('.', 10):\", \\\n", + " s.lower().endswith('.', 10))\n", + "print(\"s.lower().endswith('.', 10, 20):\", \\\n", + " s.lower().endswith('.', 10, 20))\n", + "\n", + "\n", + "print(\"s.lower().startswith('S'):\", \n", + " s.lower().startswith('S'))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "为了找到位置而进行搜索之前,你可能经常需要事先确认需要寻找的字符串在寻找对象中是否存在,这个时候,可以用 `in` 操作符:" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n" + ] + } + ], + "source": [ + "s = \"\"\"Simple is better than complex.\n", + "Complex is better than complicated.\"\"\"\n", + "# 如果你只想知道 “有没有”,而无需知道 “在哪里”,那么可以用:\n", + "print('mpl' in s)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "能搜索,就应该能替换 —— `str.replace()`,它的函数说明是这样的:\n", + "\n", + "> `str.replace(old, new[, count])`\n", + "\n", + "用 `new` 替换 `old`,替换 `count` 个实例(实例:example,每次处理的对象就是实例,即具体的操作对象),其中,`count` 这个参数是可选的。" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "s.lower().replace('mp', '[ ]', 2):\n", + "\n", + "si[ ]le is better than co[ ]lex.\n", + "complex is better than complicated.\n" + ] + } + ], + "source": [ + "s = \"\"\"Simple is better than complex.\n", + "Complex is better than complicated.\"\"\"\n", + "\n", + "# str.replace(old, new[, count])\n", + "print(\"s.lower().replace('mp', '[ ]', 2):\\n\")\n", + "print(s.lower().replace('mp', '[ ]', 2))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "另外,还有个专门替换 TAB(`\\t`)的 Method,\n", + "\n", + "> `str.expandtabs( tabsize=8)` \n", + "\n", + "它的作用非常简单,就是把字符串中的 TAB(`\\t`)替换成空格,默认是替换成 `8` 个空格 —— 当然你也可以指定究竟替换成几个空格" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\"Special cases aren't special enough to break the rules.\"" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "\"Special cases aren't special enough to break the rules.\"" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from IPython.core.interactiveshell import InteractiveShell\n", + "InteractiveShell.ast_node_interactivity = \"all\"\n", + "\n", + "# str.expandtabs(tabsize=8)\n", + "s = \"Special\\tcases\\taren't\\tspecial\\tenough\\tto\\tbreak\\tthe\\trules.\"\n", + "s.expandtabs()\n", + "s.expandtabs(2)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "### 去除子字符" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "> `str.strip([chars])`\n", + "\n", + "它最常用的场景是去除一个字符串首尾的所有空白,包括空格、TAB、换行符等等。" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "button": false, + "collapsed": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'\\t Simple is better than complex. \\t \\n'" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\t Simple is better than complex. \t \n", + "\n" + ] + }, + { + "data": { + "text/plain": [ + "'Simple is better than complex.'" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from IPython.core.interactiveshell import InteractiveShell\n", + "InteractiveShell.ast_node_interactivity = \"all\"\n", + "\n", + "s = \"\\t Simple is better than complex. \\t \\n\"\n", + "s\n", + "print(s)\n", + "s.strip()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "但是,如果给定了一个字符串作为参数,那么参数字符串中的所有字母都会被当做需要从首尾剔除的对象,直到新的首尾字母不包含在参数中,就会停止剔除:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Simple is better than complex.'" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "'mple is better than comple'" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "' is better than co'" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from IPython.core.interactiveshell import InteractiveShell\n", + "InteractiveShell.ast_node_interactivity = \"all\"\n", + "\n", + "s = \"Simple is better than complex.\"\n", + "s\n", + "s.strip('Six.p') # p 全部处理完之后,p 并不在首尾,所以原字符串中的 p 字母不受影响;\n", + "s.strip('pSix.mle') # 这一次,首尾的 p 被处理了…… 参数中的字符顺序对结果没有影响,换成 Sipx.mle 也一样……" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "还可以只对左侧处理,`str.lstrip()` 或者只对右侧处理,`str.rstrip()`" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "button": false, + "collapsed": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'Simple is better than complex.'" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "'mple is better than complex.'" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "' is better than complex.'" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from IPython.core.interactiveshell import InteractiveShell\n", + "InteractiveShell.ast_node_interactivity = \"all\"\n", + "\n", + "# str.lstrip([chars])\n", + "s = \"Simple is better than complex.\"\n", + "s\n", + "s.lstrip('Six.p') # p 全部处理完之后,p 并不在首部,所以原字符串中的 p 字母不受影响;\n", + "s.lstrip('pSix.mle') # 这一次,首部的 p 被处理了…… 参数中的字符顺序对结果没有影响,换成 Sipx.mle 也一样……" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "button": false, + "collapsed": true, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'Simple is better than complex.'" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "'Simple is better than comple'" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "'Simple is better than co'" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from IPython.core.interactiveshell import InteractiveShell\n", + "InteractiveShell.ast_node_interactivity = \"all\"\n", + "\n", + "# str.rstrip([chars])\n", + "s = \"Simple is better than complex.\"\n", + "s\n", + "s.rstrip('Six.p') # p 全部处理完之后,p 并不在尾部,所以原字符串中的 p 字母不受影响;\n", + "s.rstrip('pSix.mle') # 这一次,尾部的 p 被处理了…… 参数中的字符顺序对结果没有影响,换成 Sipx.mle 也一样……" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "### 拆分字符串" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "在计算机里,数据一般保存在文件之中。计算机擅长处理的是 “格式化数据”,即,这些数据按照一定的格式排列 —— 电子表格、数据库,就是一种保存方式。Microsoft 的 Excel 和 Apple 的 Numbers,都可以将表格导出为 `.csv` 文件。这是文本文件,里面的每一行可能由多个数据构成,数据之间用 `,`(或 `;`、`\\t`)分隔:\n", + "\n", + "```text\n", + "Name,Age,Location\n", + "John,18,New York\n", + "Mike,22,San Francisco\n", + "Janny,25,Miami\n", + "Sunny,21,Shanghai\n", + "```\n", + "\n", + "文本文件中的这样一段内容,被读进来之后,保存在某个变量,那么,那个变量的值长成这个样子:\n", + "\n", + "> `'Name,Age,Location\\nJohn,18,New York\\nMike,22,San Francisco\\nJanny,25,Miami\\nSunny,21,Shanghai'`" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Name,Age,Location\\nJohn,18,New York\\nMike,22,San Francisco\\nJanny,25,Miami\\nSunny,21,Shanghai'" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "['Name,Age,Location',\n", + " 'John,18,New York',\n", + " 'Mike,22,San Francisco',\n", + " 'Janny,25,Miami',\n", + " 'Sunny,21,Shanghai']" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from IPython.core.interactiveshell import InteractiveShell\n", + "InteractiveShell.ast_node_interactivity = \"all\"\n", + "\n", + "s = \"\"\"Name,Age,Location\n", + "John,18,New York\n", + "Mike,22,San Francisco\n", + "Janny,25,Miami\n", + "Sunny,21,Shanghai\"\"\"\n", + "\n", + "s # s 被打印出来的时候,\\n 都被转换成换行了\n", + "s.splitlines() # 注意输出结果前后的方括号,[],表示这个返回结果是一个 List" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`str.split()`, 是将一个字符串,根据分隔符进行拆分:\n", + "\n", + "> `str.split(sep=None, maxsplit=-1)`" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Mike,22,San Francisco'" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "['Mike,22,San', 'Francisco']" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "['Mike', '22', 'San Francisco']" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "['Mike', '22', 'San Francisco']" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "['Mike', '22,San Francisco']" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "['Mike,22,San Francisco']" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "['Mike', '22', 'San Francisco']" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from IPython.core.interactiveshell import InteractiveShell\n", + "InteractiveShell.ast_node_interactivity = \"all\"\n", + "\n", + "s = \"\"\"Name,Age,Location\n", + "John,18,New York\n", + "Mike,22,San Francisco\n", + "Janny,25,Miami\n", + "Sunny,21,Shanghai\"\"\"\n", + "\n", + "r = s.splitlines()[2] # 取出返回列表中索引值为 2 的那一行\n", + "r\n", + "r.split() # 如果没有给 str.split() 传递参数,那么默认为用 None 分割(各种空白,比如,\\t 和 \\r 都被当作 None)\n", + "r.split(sep=',') \n", + "r.split(',') # 上一行可以这样写。\n", + "\n", + "r.split(sep=',', maxsplit=1) # 第二个参数指定拆分几次\n", + "# r.split(sep=',', 1) # 上一行不能这样写。\n", + "r.split(sep=',', maxsplit=0) # 0 次,即不拆分\n", + "r.split(sep=',', maxsplit=-1) # 默认值是 -1,拆分全部" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "### 拼接字符串" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Python'" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "s = ''\n", + "t = ['P', 'y', 't', 'h', 'o', 'n']\n", + "s.join(t)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + } + }, + "source": [ + "### 字符串排版" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "将字符串居中放置 —— 前提是设定整行的长度:\n", + "\n", + "> `str.center(width[, fillchar])`\n", + "\n", + "注意,第 2 个参数可选,且只接收单个字符 —— `char` 是 _character_ 的缩写。" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + }, + "scrolled": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "' Sparse Is Better Than Dense! '" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "'================Sparse Is Better Than Dense!================'" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "'Sparse Is Better Than Dense!'" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "' Sparse Is Better Than Dense!'" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "'................................Sparse Is Better Than Dense!'" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from IPython.core.interactiveshell import InteractiveShell\n", + "InteractiveShell.ast_node_interactivity = \"all\"\n", + "\n", + "s = 'Sparse is better than dense!'\n", + "s.title().center(60)\n", + "s.title().center(60, '=')\n", + "s.title().center(10) # 如果宽度参数小于字符串长度,则返回原字符串\n", + "\n", + "\n", + "s = 'Sparse is better than dense!'\n", + "s.title().rjust(60)\n", + "s.title().rjust(60, '.')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "将字符串靠左或者靠右对齐放置:\n", + "\n", + "> * `str.ljust(width)`\n", + "> * `str.rjust(width)`" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "另外,还有个字符串 Method 是,将字符串转换成左侧由 `0` 填充的指定长度字符串。例如,这在批量生成文件名的时候就很有用……" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "001.mp3\n", + "002.mp3\n", + "003.mp3\n", + "004.mp3\n", + "005.mp3\n", + "006.mp3\n", + "007.mp3\n", + "008.mp3\n", + "009.mp3\n", + "010.mp3\n" + ] + } + ], + "source": [ + "for i in range(1, 11):\n", + " filename = str(i).zfill(3) + '.mp3'\n", + " print(filename)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + }, + "toc-hr-collapsed": true + }, + "source": [ + "### 格式化字符串" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "所谓对字符串进行格式化,指的是将特定变量插入字符串特定位置的过程。常用的 Methods 有两个,一个是 `str.format()`,另外一个是 `f-string`。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 使用 str.format() " + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'John is 25 years old.'" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "'Are you John? :-{+}'" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "'John is a grown up? True'" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from IPython.core.interactiveshell import InteractiveShell\n", + "InteractiveShell.ast_node_interactivity = \"all\"\n", + "\n", + "name = 'John'\n", + "age = 25\n", + "'{} is {} years old.'.format(name, age)\n", + "# 不写占位符索引就默认每个占位符的索引从第一个开始是 0, 1, 2 ...(占位符数量 - 1)\n", + "# '{} {}'.format(a, b) 和 '{0} {1}'.format(a, b) 是一样的。\n", + "\n", + "# '{0} is {2} years old.'.format(name, age)\n", + "# 这一句会报错,因为 2 超出实际参数索引极限\n", + "\n", + "# 两个连续使用的大括号,不被认为是占位符;且只打印出一对大括号\n", + "\"Are you {0}? :-{{+}}\".format(name)\n", + "\n", + "# \"%s is %d years old.\" % (name, age)\n", + "# 上一行这是兼容 Python 2 的老式写法,可以从此忽略……\n", + "\n", + "# str.format() 里可以直接写表达式……\n", + "'{} is a grown up? {}'.format(name, age >= 18)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 使用 f-string" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "_f-string_ 与 `str.format()` 的功用差不多,只是写法简洁一些 —— 在字符串标示之前加上一个字母 `f`:" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'John is 25 years old.'" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "'John is a grown up? True'" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from IPython.core.interactiveshell import InteractiveShell\n", + "InteractiveShell.ast_node_interactivity = \"all\"\n", + "\n", + "# https://docs.python.org/3/library/stdtypes.html#printf-style-bytes-formatting\n", + "# f-string\n", + "\n", + "name = 'John'\n", + "age = 25\n", + "f'{name} is {age} years old.'\n", + "f'{name} is a grown up? {age >= 18}'" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "只不过,str.format() 的用法中,索引顺序可以任意指定,于是相对更为灵活,下面的例子只是为了演示参数位置可以任意指定:" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'25 is John years old.'" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "name = 'John'\n", + "age = 25\n", + "'{1} is {0} years old.'.format(name, age)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "button": false, + "new_sheet": false, + "run_control": { + "read_only": false + }, + "toc-hr-collapsed": false + }, + "source": [ + "### 字符串属性" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "字符串还有一系列的 Methods,返回的是布尔值,用来判断字符串的构成属性:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "'1234567890'.isalnum(): True\n", + "'abcdefghij'.isalpha(): True\n", + "'山巅一寺一壶酒'.isascii(): False\n", + "'0.123456789'.isdecimal(): False\n", + "'0.123456789'.isdigit(): False\n", + "'0.123456789'.isnumeric(): False\n", + "'Continue'.islower(): False\n", + "'Simple Is Better Than Complex'.isupper(): False\n", + "'Simple Is Better Than Complex'.istitle(): True\n", + "'\t'.isprintable(): False\n", + "'\t'.isspace(): True\n", + "'for'.isidentifier(): True\n" + ] + } + ], + "source": [ + "# str.isalnum()\n", + "print(\"'1234567890'.isalnum():\", \\\n", + " '1234567890'.isalnum()) # '3.14'.isalnum() 返回的是 False\n", + "\n", + "# str.isalpha()\n", + "print(\"'abcdefghij'.isalpha():\", \\\n", + " 'abcdefghij'.isalpha()) \n", + "\n", + "# str.isascii()\n", + "print(\"'山巅一寺一壶酒'.isascii():\", \\\n", + " '山巅一寺一壶酒'.isascii())\n", + "\n", + "# str.isdecimal()\n", + "print(\"'0.123456789'.isdecimal():\", \\\n", + " '0.1234567890'.isdecimal())\n", + "\n", + "# str.isdigit()\n", + "print(\"'0.123456789'.isdigit():\", \\\n", + " '0.1234567890'.isdigit()) # 注意,如果字符串是 identifier,返回值也是 False\n", + "\n", + "# str.isnumeric()\n", + "print(\"'0.123456789'.isnumeric():\", \\\n", + " '0.1234567890'.isnumeric())\n", + "\n", + "# str.islower()\n", + "print(\"'Continue'.islower():\", \\\n", + " 'Continue'.islower())\n", + "\n", + "# str.isupper()\n", + "print(\"'Simple Is Better Than Complex'.isupper():\", \\\n", + " 'Simple Is Better Than Complex'.isupper())\n", + "\n", + "# str.istitle()\n", + "print(\"'Simple Is Better Than Complex'.istitle():\", \\\n", + " 'Simple Is Better Than Complex'.istitle())\n", + "\n", + "# str.isprintable()\n", + "print(\"'\\t'.isprintable():\", \\\n", + " '\\t'.isprintable())\n", + "\n", + "# str.isspace()\n", + "print(\"'\\t'.isspace():\", \\\n", + " '\\t'.isspace())\n", + "\n", + "# str.isidentifier()\n", + "print(\"'for'.isidentifier():\", \\\n", + " 'for'.isidentifier())" + ] + } + ], + "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.11.4" + }, + "toc-autonumbering": true + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/容器.md b/容器.md new file mode 100644 index 0000000..08143ea --- /dev/null +++ b/容器.md @@ -0,0 +1,1344 @@ +# 数据容器 + +在 Python 中,有个**数据容器**(Container)的概念。 + +其中包括**字符串**、由 `range()` 函数生成的**等差数列**、**列表**(List)、**元组**(Tuple)、**集合**(Set)、**字典**(Dictionary)。 + +这些容器,各有各的用处。其中又分为*可变*容器(Mutable)和*不可变*容器(Immutable)。可变的有列表、集合、字典;不可变的有字符串、`range()` 生成的等差数列、元组。集合,又分为 *Set* 和 *Frozen Set*;其中,Set 是*可变的*,Frozen Set 是*不可变的*。 + +字符串、由 `range()` 函数生成的等差数列、列表、元组是**有序类型**(Sequence Type),而集合与字典是*无序*的。 + +## 迭代(Iterate) + +数据容器里的元素是可以被**迭代的**(Iterable),它们其中包含的元素,可以被逐个访问,以便被处理。 + +对于数据容器,有一个操作符,`in`,用来判断某个元素是否属于某个容器。 + + +```python +for c in 'Python': + print(c) +``` + + P + y + t + h + o + n + +```python +for i in range(10): + print(i) +``` + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + + +当然,有时候我们也需要比较复杂的计数器,不过,Python 也不只有 `for` 循环,还有 `while` 循环,在必要的时候可以写复杂的计数器。 + +## 列表(List) + +列表和字符串一样,是个*有序类型*(Sequence Type)的容器,其中包含着有索引编号的元素。 + +列表中的元素可以是不同类型。不过,在解决现实问题的时候,我们总是倾向于创建由同一个类型的数据构成的列表。遇到由不同类型数据构成的列表,我们更可能做的是想办法把不同类型的数据分门别类地拆分出来,整理清楚 —— 这种工作甚至有个专门的名称与之关联:*数据清洗*。 + +### 列表的生成 + +生成一个列表,有以下几种方式: + + +```python +a_list = [] +b_list = [1, 2, 3] +list(), or list(iterable) # 这是 Type Casting +[(expression with x) for x in iterable] +``` + + +```python +a_list = [] +a_list.append(1) +a_list.append(2) +print(a_list, f'has a length of {len(a_list)}.') + +#range() 返回的不是 list,需要用 list() 转换,否则也没办法调用 .append() +b_list = list(range(1, 9)) +b_list.append(11) +print(b_list, f'has a length of {len(b_list)}.') + + +c_list = [2**x for x in range(8)] +print(c_list, f'has a length of {len(c_list)}.') +``` + + [1, 2] has a length of 2. + [1, 2, 3, 4, 5, 6, 7, 8, 11] has a length of 9. + [1, 2, 4, 8, 16, 32, 64, 128] has a length of 8. + + +```python +[2**x for x in range(8)] +``` + +这种做法,叫做 **[List Comprehension](https://docs.python.org/3.7/tutorial/datastructures.html#tut-listcomps)**。 + +List comprehension 可以嵌套使用 `for`,甚至可以加上条件 `if`。官方文档里有个例子,是用来把两个元素并不完全相同的列表去同后拼成一个列表(下面稍作了改写): + +```python +import random + +n = 10 + +# 生成一个 n 个元素的序列,每个元素是 1~100 之间的随机数 +a_list = [random.randrange(1, 100) for i in range(n)] +print(f'a_list comprehends {len(a_list)} random numbers: {a_list}') + +# 从 a_list 里把偶数都挑出来 +b_list = [x for x in a_list if x % 2 == 0] +print(f'... and it has {len(b_list)} even numbers: {b_list}') +``` + + a_list comprehends 10 random numbers: [52, 34, 7, 96, 33, 79, 95, 18, 37, 46] + ... and it has 5 even numbers: [52, 34, 96, 18, 46] + + +### 列表的操作符 + +列表的操作符和字符串一样,因为它们都是有序容器。列表的操作符有: + +> * 拼接:`+`(与字符串不一样的地方是,不能用空格 `' '` 了) +> * 复制:`*` +> * 逻辑运算:`in` 和 `not in`,`<`、`<=`、`>`、`>=`、`!=`、`==` + +而后两个列表也和两个字符串一样,可以被比较,即,可以进行逻辑运算;比较方式也跟字符串一样,从两个列表各自的第一个元素开始逐个比较,“一旦决出胜负马上停止”: + + +```python +from IPython.core.interactiveshell import InteractiveShell +InteractiveShell.ast_node_interactivity = "all" + +a_list = [1, 2, 3] +b_list = [4, 5, 6] +c_list = a_list + b_list * 3 +c_list +7 not in c_list +a_list > b_list +``` + + + [1, 2, 3, 4, 5, 6, 4, 5, 6, 4, 5, 6] + + + True + + + False + +### 根据索引提取列表元素 + +列表当然也可以根据索引操作,但由于列表是可变序列,所以,不仅可以提取,还可以删除,甚至替换。 + + +```python +import random +n = 3 +a_list = [random.randrange(65, 91) for i in range(n)] +b_list = [chr(random.randrange(65, 91)) for i in range(n)] +print(a_list) +c_list = a_list + b_list + a_list * 2 +print(c_list) + +print() +# 根据索引提取(Slicing) +print(c_list[3]) # 返回索引值为 3 的元素值 +print(c_list[:]) # 相当于 c_list,返回整个列表 +print(c_list[5:]) # 从索引为 5 的值开始直到末尾 +print(c_list[:3]) # 从索引 0 开始,直到索引 3 之前(不包括 3) +print(c_list[2:6]) # 从索引 2 开始,直到索引 6 之前(不包括 6) + +print() +# 根据索引删除 +del c_list[3] +print(c_list) # del 是个命令,del c_list[3] 是一个语句;不能这么写:print(del c_list[3]) +del c_list[5:8] +print(c_list) + +print() +# 根据索引替换 +c_list[1:5:2] = ['a', 2] # s[start:stop:step] = t,跟 range 的三个参数类似; + # len(t) = len([start:stop:step]) 必须为真 +print(c_list) +``` + + [74, 75, 88] + [74, 75, 88, 'M', 'V', 'G', 74, 75, 88, 74, 75, 88] + + M + [74, 75, 88, 'M', 'V', 'G', 74, 75, 88, 74, 75, 88] + ['G', 74, 75, 88, 74, 75, 88] + [74, 75, 88] + [88, 'M', 'V', 'G'] + + [74, 75, 88, 'V', 'G', 74, 75, 88, 74, 75, 88] + [74, 75, 88, 'V', 'G', 74, 75, 88] + + [74, 'a', 88, 2, 'G', 74, 75, 88] + + +需要注意的地方是:**列表**(List)是可变序列,而**字符串**(str)是不可变序列,所以,对字符串来说,虽然也可以根据索引提取,但没办法根据索引删除或者替换。 + + +```python +s = 'Python'[2:5] +print(s) +del s[2] # 这一句会报错 +``` + + tho + + --------------------------------------------------------------------------- + + TypeError Traceback (most recent call last) + + in + 1 s = 'Python'[2:5] + 2 print(s) + ----> 3 del s[3] # 这一句会报错 + + + TypeError: 'str' object doesn't support item deletion + + +之前提到过: + +> 字符串常量(String Literal)是不可变有序容器,所以,虽然字符串也有一些 Methods 可用,但那些 Methods 都不改变它们自身,而是在操作后返回一个值给另外一个变量。 + +而对于列表这种*可变容器*,我们可以对它进行操作,结果是*它本身被改变*了。 + + +```python +s = 'Python' +L = list(s) +print(s) +print(L) +del L[2] +print(L) # 用 del 对 L 操作之后,L 本身少了 1 个元素 +``` + + Python + ['P', 'y', 't', 'h', 'o', 'n'] + ['P', 'y', 'h', 'o', 'n'] + + +### 列表可用的内建函数 + +列表和字符串都是容器,它们可使用的内建函数也其实都是一样的: + +> * `len()` +> * `max()` +> * `min()` + + +```python +import random +n = 3 + +# 生成 3 个随机数,构成一个列表 +a_list = [random.randrange(65, 91) for i in range(n)] +b_list = [chr(random.randrange(65, 91)) for i in range(n)] +print(a_list) +print(b_list) + +# 列表可以使用操作符 + 和* +c_list = a_list + b_list + a_list * 2 +print(c_list) + +a_list *= 3 +print(a_list) + +# 内建函数操作 len()、max()、min() +print(len(c_list)) +print(max(b_list)) # 内建函数内部做了异常处理,可以在字符之间或者数字之间进行比较 —— 初学者最讨厌这种事情了…… +print(min(b_list)) # 注意,max() 和 min() 应用的是 b_list, len() 应用的是 c_list —— 请自行找到对应的 list 进行分析。 + +print('X' not in b_list) +``` + + [89, 84, 85] + ['X', 'B', 'X'] + [89, 84, 85, 'X', 'B', 'X', 89, 84, 85, 89, 84, 85] + [89, 84, 85, 89, 84, 85, 89, 84, 85] + 12 + X + B + False + + +### Methods + +字符串常量和 range() 都是不可变的(Immutable);而列表则是**可变类型**(Mutable type),所以,它最起码可以被排序 —— 使用 `sort()` Method: + + +```python +import random +n = 10 +a_list = [random.randrange(1, 100) for i in range(n)] +print(f'a_list comprehends {len(a_list)} random numbers:\n', a_list) + +a_list.sort() +print('the list sorted:\n', a_list) + +a_list.sort(reverse=True) #reverse 参数,默认是 False +print('the list sorted reversely:\n', a_list) +``` + + a_list comprehends 10 random numbers: + [98, 9, 95, 15, 80, 70, 98, 82, 88, 46] + the list sorted: + [9, 15, 46, 70, 80, 82, 88, 95, 98, 98] + the list sorted reversely: + [98, 98, 95, 88, 82, 80, 70, 46, 15, 9] + + +如果列表中的元素全都是由字符串构成的,当然也可以排序: + + +```python +import random +n = 10 + +a_list = [chr(random.randrange(65, 91)) for i in range(n)] +# chr() 函数会返回指定 ascii 码的字符,ord('A') 是 65 +print(f'a_list comprehends {len(a_list)} random string elements:\n', a_list) + +a_list.sort() +print('the list sorted:\n', a_list) + +a_list.sort(reverse=True) #reverse 参数,默认是 False +print('the list sorted reversely:\n', a_list) + +print() + +b_list = [chr(random.randrange(65, 91)) +\ + chr(random.randrange(97, 123))\ + for i in range(n)] +# 可以在行末加上 \ 符号,表示 “该行未完待续……” + +print(f'b_list comprehends {len(b_list)} random string elements:\n', b_list) + +b_list.sort() +print('the sorted:\n', b_list) + +b_list.sort(key=str.lower, reverse=True) +# key 参数,默认是 None +# key=str.lower 的意思是,在比较的时候,先全都转换成小写再比较…… +# —— 但并不改变原有值 +print('the sorted reversely:\n', b_list) +``` + + a_list comprehends 10 random string elements: + ['B', 'U', 'H', 'D', 'C', 'V', 'V', 'Q', 'U', 'P'] + the list sorted: + ['B', 'C', 'D', 'H', 'P', 'Q', 'U', 'U', 'V', 'V'] + the list sorted reversely: + ['V', 'V', 'U', 'U', 'Q', 'P', 'H', 'D', 'C', 'B'] + + b_list comprehends 10 random string elements: + ['Nl', 'Mh', 'Ta', 'By', 'Ul', 'Nc', 'Gu', 'Rp', 'Pv', 'Bu'] + the sorted: + ['Bu', 'By', 'Gu', 'Mh', 'Nc', 'Nl', 'Pv', 'Rp', 'Ta', 'Ul'] + the sorted reversely: + ['Ul', 'Ta', 'Rp', 'Pv', 'Nl', 'Nc', 'Mh', 'Gu', 'By', 'Bu'] + + +**注意**:不能乱比较…… 被比较的元素应该是同一类型 —— 所以,不是由同一种数据类型元素构成的列表,不能使用 `sort()` Method。下面的代码会报错: + + +```python +a_list = [1, 'a', 'c'] +a_list = a_list.sort() # 这一句会报错 +``` + + + --------------------------------------------------------------------------- + + TypeError Traceback (most recent call last) + + in + 1 a_list = [1, 'a', 'c'] + ----> 2 a_list = a_list.sort() # 这一句会报错 + + + TypeError: '<' not supported between instances of 'str' and 'int' + + +**可变序列**还有一系列可用的 **Methods**:`a.append()`,`a.clear()`,`a.copy()`,`a.extend(t)`,`a.insert(i,x)`,`a.pop([i])`,`a.remove(x)`,`a.reverse()`…… + + +```python +import random +n = 3 +a_list = [random.randrange(65, 91) for i in range(n)] +b_list = [chr(random.randrange(65, 91)) for i in range(n)] +print(a_list) +c_list = a_list + b_list + a_list * 2 +print(c_list) + +# 在末尾追加一个元素 +c_list.append('100') +print(c_list) + +# 清空序列 +print() +print(a_list) +a_list.clear() +print(a_list) + +print() +print("拷贝") +# 拷贝一个列表 +d_list = c_list.copy() +print(d_list) +del d_list[6:8] +print(d_list) +print(c_list) # 对一个拷贝操作,不会更改 “原件” + +print() +# 演示拷贝 .copy() 与赋值 = 的不同 +e_list = d_list +del e_list[6:8] +print(e_list) +print(d_list) # 对 e_list 操作,相等于对 d_list 操作 + +# 在末尾追加一个列表 +print() +print(a_list) +a_list.extend(c_list) # 相当于 a_list += c_list +print(a_list) + +# 在某索引位置插入一个元素 +print() +print(a_list) +a_list.insert(1, 'example') # 在索引 1 的位置插入 'example' +a_list.insert(3, 'example') # 在索引 3 的位置插入 'example'; +print(a_list) + +# 排序 + +# a_list.sort() 这一句会出错,因为当前列表中的元素,是 int 和 str 混合的。 + +print() +print(a_list) +a_list.reverse() +print(a_list) +x = a_list.reverse() # reverse() 只对当前序列操作,并不返回一个逆序列表;返回值是 None +print(x) +``` + + [76, 78, 73] + [76, 78, 73, 'R', 'X', 'B', 76, 78, 73, 76, 78, 73] + [76, 78, 73, 'R', 'X', 'B', 76, 78, 73, 76, 78, 73, '100'] + + [76, 78, 73] + [] + + 拷贝 + [76, 78, 73, 'R', 'X', 'B', 76, 78, 73, 76, 78, 73, '100'] + [76, 78, 73, 'R', 'X', 'B', 73, 76, 78, 73, '100'] + [76, 78, 73, 'R', 'X', 'B', 76, 78, 73, 76, 78, 73, '100'] + + [76, 78, 73, 'R', 'X', 'B', 78, 73, '100'] + [76, 78, 73, 'R', 'X', 'B', 78, 73, '100'] + + [] + [76, 78, 73, 'R', 'X', 'B', 76, 78, 73, 76, 78, 73, '100'] + + [76, 78, 73, 'R', 'X', 'B', 76, 78, 73, 76, 78, 73, '100'] + [76, 'example', 78, 'example', 73, 'R', 'X', 'B', 76, 78, 73, 76, 78, 73, '100'] + + [76, 'example', 78, 'example', 73, 'R', 'X', 'B', 76, 78, 73, 76, 78, 73, '100'] + ['100', 73, 78, 76, 73, 78, 76, 'B', 'X', 'R', 73, 'example', 78, 'example', 76] + None + + +有一个命令、两个 Methods 与删除单个元素相关联,`del`,`a.pop([i])`,`a.remove(x)`,请注意它们之间的区别。 + + +```python +import random +n = 3 +a_list = [random.randrange(65, 91) for i in range(n)] +print(a_list) + +# 插入 +print() +a_list.insert(1, 'example') # 在索引 1 的位置插入 'example' + +# 删除 +print() +print(a_list) +a_list.remove('example') # 去除 'example' 这个元素,如果有多个 'example',只删除第一个 +print(a_list) + +# pop() 删除并返回被删除的值 + +print() +print(a_list) +p = a_list.pop(2) # 去除索引为 2 的元素,且返回元素的值,赋值给 p +print(a_list) +print(p) + +# pop() 与 del,或者 remove() 的区别 +print() +a_list.insert(2, 'example') +a_list.insert(2, 'example') +print(a_list) +del a_list[2] +print(a_list) + +print() +print(a_list.remove('example')) # a_list.remove() 这个 Method 的返回值是 None +print(a_list) +``` + + [88, 84, 69] + + [88, 'example', 84, 69] + [88, 84, 69] + + [88, 84, 69] + [88, 84] + 69 + + [88, 84, 'example', 'example'] + [88, 84, 'example'] + + None + [88, 84] + + +## 元组(Tuple) + +列表和元组之间的主要区别只有两个: + +> * List 是*可变*有序容器,Tuple 是*不可变*有序容器。 +> * List 用*方括号*标识 `[]`,Tuple 用*圆括号* 标识 `()`。 + +创建一个元组的时候,用圆括号: + +```python +a = () +``` + +这样就创建了一个空元组。 + +多个元素之间,用 `,` 分离。 + +创建一个含多个元素的元组,可以省略这个括号。 + + +```python +a = 1, 2, 3 # 不建议这种写法 +b = (1, 2, 3) # 在创建元组的时候建议永远不省略圆括号…… +print(a) +print(b) +a == b +``` + + (1, 2, 3) + (1, 2, 3) + + True + +**注意**:创建单个元素的元组,无论是否使用圆括号,在那唯一的元素后面一定要*补上一个逗号* `,`: + + +```python +from IPython.core.interactiveshell import InteractiveShell +InteractiveShell.ast_node_interactivity = "all" + +a = 2, # 注意这个末尾的逗号 , 它使得 a 变量被定义为一个元组,而不是数字 +a + +b = 2 # 整数,赋值 +b + +c = (2) # 不是元组 +c +type(c) # 还是 int + +d = (2,) # 这才是元组 +d +a == d +``` + + + (2,) + + + 2 + + + 2 + + + int + + + (2,) + + + True + +元组是不可变序列,所以,你没办法从里面删除元素。 + +但是,你可以在末尾追加元素。所以,严格意义上,对元组来讲,“不可变” 的意思是说,“**当前已有部分不可变**”…… + + +```python +a = 1, +print(a) +print(id(a)) +a += 3, 5 +print(a) +print(id(a)) # id 并不相同 —— 实际上是在内存中另外新创建了一个元组…… +``` + + (1,) + 4593032496 + (1, 3, 5) + 4592468976 + + +List 和 Tuple 的区别。首先是使用场景,在将来需要更改的时候,创建 List +;在将来不需要更改的时候,创建 Tuple。其次,从计算机的角度来看,Tuple 相对于 List 占用更小的内存。 + + +```python +from IPython.core.interactiveshell import InteractiveShell +InteractiveShell.ast_node_interactivity = "all" + +n = 10000 #@param {type:"number"} +a = range(n) +b = tuple(a) # 把 a 转换成元组 +c = list(a) # 把 a 转换成列表 +a.__sizeof__() +b.__sizeof__() +c.__sizeof__() +``` + + + 48 + + + 80024 + + + 90088 + +`range()` 函数返回的等差数列就是一个 Tuple —— `range(6)` 就相当于 `(0, 1, 2, 3, 4, 5)`。 + +## 集合(Set) + +**集合**(Set)这个容器类型与列表不同的地方在于,首先它*不包含重合元素*,其次它是*无序*的;进而,集合又分为两种,Set,*可变的*,Frozen Set,*不可变的*。 + +创建一个集合,用**花括号** `{}` 把元素括起来,用 `,` 把元素隔开: + + +```python +primes = {2, 3, 5, 7, 11, 13, 17} +primes +``` + + + {2, 3, 5, 7, 11, 13, 17} + +### 创建 + +注意:创建空集合的时候,必须用 `set()`,而不能用 `{}`: + + +```python +from IPython.core.interactiveshell import InteractiveShell +InteractiveShell.ast_node_interactivity = "all" + +a = {} # 注意这样创建的是一个 dict(字典),而不是 set 集合 +b = set() # 这样创建的才是空集合 +type(a) +type(b) +``` + + + dict + + + set + +也可以将序列数据转换(Casting)为集合。转换后,返回的是一个已**去重**的集合。 + + +```python +from IPython.core.interactiveshell import InteractiveShell +InteractiveShell.ast_node_interactivity = "all" + +a = "abcabcdeabcdbcdef" +b = range(10) +c = [1, 2, 2, 3, 3, 1] +d = ('a', 'b', 'e', 'b', 'a') +set(a) +set(b) +set(c) +set(d) +``` + + + {'a', 'b', 'c', 'd', 'e', 'f'} + + + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} + + + {1, 2, 3} + + + {'a', 'b', 'e'} + +Set 当然也可以进行 *Comprehension*: + + +```python +a = "abcabcdeabcdbcdef" +b = {x for x in a if x not in 'abc'} +b +``` + + + {'d', 'e', 'f'} + +### 操作 + +将序列类型数据转换成 Set,就等于**去重**。当然,也可以用 `in` 来判断某个元素是否属于这个集合。`len()`、`max()`、`min()`,也都可以用来操作 Set,但 `del` 却不行 —— 因为 Set 中的元素没有索引(它不是有序容器)。从 Set 里删除元素,得用 `set.remove(elem)`;而 Frozen Set 是不可变的,所以不能用 `set.remove(elem)` 操作。 + +对于集合,有相应的操作符可以对它们进行集合运算: + +> * 并集:`|` +> * 交集:`&` +> * 差集:`-` +> * 对称差集:`^` + +当我们需要管理很多用户时,集合就可以派上很大用场。 + +假定两个集合中有些人是 admins,有些人是 moderators: + +```python +admins = {'Moose', 'Joker', 'Joker'} +moderators = {'Ann', 'Chris', 'Jane', 'Moose', 'Zero'} +``` + +那么: + + +```python +admins = {'Moose', 'Joker', 'Joker'} +moderators = {'Ann', 'Chris', 'Jane', 'Moose', 'Zero'} + +admins # 去重自动完成 +'Joker' in admins # Joker 是否是 admins? +'Joker' in moderators # Joker 是否是 moderator? +admins | moderators # admins、moderator,或者身兼两职的,即,两个角色中的所有人 in admins or moderators or both +admins & moderators # 既是 admins 又是 moderator 的都有谁?in both admins and moderators +admins - moderators # 是 admins 但不是 moderator 的都有谁?in admins but not in moderators +admins ^ moderators # admins 和 moderator 中不是身兼两职的都有谁?in admins or moderator but not both +``` + + + {'Joker', 'Moose'} + + + True + + + False + + + {'Ann', 'Chris', 'Jane', 'Joker', 'Moose', 'Zero'} + + + {'Moose'} + + + {'Joker'} + + + {'Ann', 'Chris', 'Jane', 'Joker', 'Zero'} + +以上的操作符,都有另外一个版本,即,用 Set 这个类的 Methods 完成。 + +| 意义 | 操作符 | Methods | Methods 相当于 | +| :------: | :----: | :---------------------: | :--: | +| 并集 | | | `set.union(*others)` | set | other | ... | +| 交集 | `&` | `set.intersection(*others)` | `set & other & ...` | +| 差集 | `-` | `set.difference(*others)` | `set - other - ...` | +| 对称差集 | `^` | `set.symmetric_difference(other)` | `set ^ other` | + +注意,并集、交集、差集的 Methods,可以接收多个集合作为参数 `(*other)`,但对称差集 Method 只接收一个参数 `(other)`。 + +对于集合,推荐更多使用 Methods 而不是操作符的主要原因是:更易读 —— 对人来说,因为有意义、有用处的代码终将需要人去维护。 + + +```python +from IPython.core.interactiveshell import InteractiveShell +InteractiveShell.ast_node_interactivity = "all" + +admins = {'Moose', 'Joker', 'Joker'} +moderators = {'Chris', 'Moose', 'Jane', 'Zero'} + +admins.union(moderators) +admins.intersection(moderators) +admins.difference(moderators) +admins.symmetric_difference(moderators) +``` + + + {'Chris', 'Jane', 'Joker', 'Moose', 'Zero'} + + + {'Moose'} + + + {'Joker'} + + + {'Chris', 'Jane', 'Joker', 'Zero'} + +### 逻辑运算 + +两个集合之间可以进行逻辑比较,返回布尔值。 + +**set** `==` **other** +> `True`: set 与 other 相同 + +**set** `!=` **other** +> `True`: set 与 other 不同 + +**isdisjoint**(_other_) +> `True`: set 与 other 非重合;即,`set & other == None` + +**issubset**(_other_),**set** `<=` **other** +> `True`: set 是 other 的子集 + +**set** `<` **other** +> `True`: set 是 other 的真子集,相当于 `set <= other && set != other` + +**issuperset**(_other_),**set** `>=` **other** +> `True`: set 是 other 的超集 + +**set** `>` **other** +> `True`: set 是 other 的真超集,相当于 `set >= other && set != other` + +### 更新 + +对于集合,有以下更新它自身的 Method: + +**add**(*elem*) +> 把 elem 加入集合 + +**remove**(*elem*) +> 从集合中删除 elem;如果集合中不包含该 elem,会产生 KeyError 错误。 + +**pop**() +> 从集合中随机删除一个元素,并返回删除的元素的值,针对空集合做此操作会产生 KeyError 错误。 + +**clear**() +从集合中删除所有元素。 + +**set.update**(*_others_),相当于 `set |= other | ...` +> 更新 set, 加入 others 中的所有元素; + +**set.intersection_update**(*_others_),相当于 `set &= other & ...` +> 更新 set, 保留同时存在于 set 和所有 others 之中的元素; + +**set.difference_update**(*_others_),相当于 `set -= other | ...` +> 更新 set, 删除所有在 others 中存在的元素; + +**set.symmetric_difference_update**(_other_),相当于 `set ^= other` +> 更新 set, 只保留存在于 set 或 other 中的元素,但不保留同时存在于 set 和 other 中的元素;**注意**,该 Method *只接收一个参数*。 + +## 字典(Dictionary) + +Map 是容器中的单独一类,**映射**(Map)容器。映射容器只有一种,叫做**字典**(Dictionary)。先看一个例子: + + +```python +phonebook = {'ann':6575, 'bob':8982, 'joe':2598, 'zoe':1225} +phonebook +``` + +字典里的每个元素,由两部分组成,_key_(键)和 _value_(值),二者由一个冒号连接。 + +比如,`'ann':6575` 这个字典元素,_key_ 是 `'ann'`,_value_ 是 `6575`。 + +字典直接使用 _key_ 作为索引,并映射到与它匹配的 _value_: + + +```python +phonebook = {'ann':6575, 'bob':8982, 'joe':2598, 'zoe':1225} +phonebook['bob'] +``` + + + 8982 + +在同一个字典里,_key_ 都是唯一的。当创建字典的时候,如果其中有重复的 _key_ 的话,就跟 Set 那样会 “**自动去重**” —— 保留的是众多重复的 _key_ 中的最后一个 _key:value_(或者说,最后一个 _key:value_ “之前那个 _key_ 的 _value_ 被**更新**了”)。字典这个数据类型之所以叫做 Map(映射),是因为字典里的 _key_ 都映射且只映射一个对应的 _value_。 + + +```python +phonebook = {'ann':6575, 'bob':8982, 'joe':2598, 'zoe':1225, 'ann':6585} +phonebook +``` + + + {'ann': 6585, 'bob': 8982, 'joe': 2598, 'zoe': 1225} + +### 字典的生成 + + +```python +from IPython.core.interactiveshell import InteractiveShell +InteractiveShell.ast_node_interactivity = "all" + +aDict = {} +bDict = {'a':1, 'b':2, 'c':3} +aDict +bDict +``` + + + {} + + + {'a': 1, 'b': 2, 'c': 3} + +### 更新某个元素 + + +```python +from IPython.core.interactiveshell import InteractiveShell +InteractiveShell.ast_node_interactivity = "all" + +phonebook1 = {'ann':6575, 'bob':8982, 'joe':2598, 'zoe':1225, 'ann':6585} + +phonebook1['joe'] +phonebook1['joe'] = 5802 +phonebook1 +phonebook1['joe'] +``` + + + 2598 + + + {'ann': 6585, 'bob': 8982, 'joe': 5802, 'zoe': 1225} + + + 5802 + +### 添加元素 + + +```python +from IPython.core.interactiveshell import InteractiveShell +InteractiveShell.ast_node_interactivity = "all" + +phonebook1 = {'ann':6575, 'bob':8982, 'joe':2598, 'zoe':1225, 'ann':6585} +phonebook2 = {'john':9876, 'mike':5603, 'stan':6898, 'eric':7898} + +phonebook1.update(phonebook2) +phonebook1 +``` + + + {'ann': 6585, + 'bob': 8982, + 'joe': 2598, + 'zoe': 1225, + 'john': 9876, + 'mike': 5603, + 'stan': 6898, + 'eric': 7898} + +### 删除某个元素 + + +```python +from IPython.core.interactiveshell import InteractiveShell +InteractiveShell.ast_node_interactivity = "all" + +phonebook1 = {'ann':6575, 'bob':8982, 'joe':2598, 'zoe':1225, 'ann':6585} + +del phonebook1['ann'] +phonebook1 +``` + + + {'bob': 8982, 'joe': 2598, 'zoe': 1225} + +### 逻辑操作符 + + +```python +phonebook1 = {'ann':6575, 'bob':8982, 'joe':2598, 'zoe':1225, 'ann':6585} + +'ann' in phonebook1 + +phonebook1.keys() +'stan' in phonebook1.keys() + +phonebook1.values() +1225 in phonebook1.values() + +phonebook1.items() +('stan', 6898) in phonebook1.items() +``` + + + True + + + dict_keys(['ann', 'bob', 'joe', 'zoe']) + + + False + + + dict_values([6585, 8982, 2598, 1225]) + + + True + + + dict_items([('ann', 6585), ('bob', 8982), ('joe', 2598), ('zoe', 1225)]) + + + False + +### 可用来操作的内建函数 + + +```python +from IPython.core.interactiveshell import InteractiveShell +InteractiveShell.ast_node_interactivity = "all" + +phonebook1 = {'ann':6575, 'bob':8982, 'joe':2598, 'zoe':1225, 'ann':6585} +phonebook2 = {'john':9876, 'mike':5603, 'stan':6898, 'eric':7898} +phonebook1.update(phonebook2) + +len(phonebook1) +max(phonebook1) +"a" > "z" +min(phonebook1) +list(phonebook1) +tuple(phonebook1) +set(phonebook1) +sorted(phonebook1) +sorted(phonebook1, reverse=True) +``` + + + 8 + + + 'zoe' + + + False + + + 'ann' + + + ['ann', 'bob', 'joe', 'zoe', 'john', 'mike', 'stan', 'eric'] + + + ('ann', 'bob', 'joe', 'zoe', 'john', 'mike', 'stan', 'eric') + + + {'ann', 'bob', 'eric', 'joe', 'john', 'mike', 'stan', 'zoe'} + + + ['ann', 'bob', 'eric', 'joe', 'john', 'mike', 'stan', 'zoe'] + + + ['zoe', 'stan', 'mike', 'john', 'joe', 'eric', 'bob', 'ann'] + +注意:sort 是应用在 list 上的方法,属于列表的成员方法,sorted 可以对所有可迭代的对象进行排序操作。 +```python +sorted(iterable[, cmp[, key[, reverse]]]) +``` + +### 常用 Methods + + +```python +from IPython.core.interactiveshell import InteractiveShell +InteractiveShell.ast_node_interactivity = "all" + +phonebook1 = {'ann':6575, 'bob':8982, 'joe':2598, 'zoe':1225, 'ann':6585} +phonebook2 = {'john':9876, 'mike':5603, 'stan':6898, 'eric':7898} + +phonebook3 = phonebook2.copy() +phonebook3 + +phonebook3.clear() +phonebook3 + +phonebook2 # .copy() 的 “原件” 不会发生变化 + +p = phonebook1.popitem() +p +phonebook1 + +p = phonebook1.pop('adam', 3538) +p +phonebook1 + +p = phonebook1.get('adam', 3538) +p +phonebook1 + +p = phonebook1.setdefault('adam', 3538) +p +phonebook1 +``` + + + {'john': 9876, 'mike': 5603, 'stan': 6898, 'eric': 7898} + + + {} + + + {'john': 9876, 'mike': 5603, 'stan': 6898, 'eric': 7898} + + + ('zoe', 1225) + + + {'ann': 6585, 'bob': 8982, 'joe': 2598} + + + 3538 + + + {'ann': 6585, 'bob': 8982, 'joe': 2598} + + + 3538 + + + {'ann': 6585, 'bob': 8982, 'joe': 2598} + + + 3538 + + + {'ann': 6585, 'bob': 8982, 'joe': 2598, 'adam': 3538} + +## 迭代各种容器中的元素 + +我们总是有这样的需求:对容器中的元素逐一进行处理(运算)。这样的时候,我们就用 `for` 循环去迭代它们。 + +对于迭代 `range()` 和 `list` 中的元素我们已经很习惯了: + + +```python +for i in range(3): + print(i) +``` + + 0 + 1 + 2 + +```python +for i in [1, 2, 3]: + print(i) +``` + + 1 + 2 + 3 + + +### 迭代的同时获取索引 + +有时,我们想同时得到有序容器中的元素及其索引,那么可以调用 `enumerate()` 函数来帮我们: + + +```python +s = 'Python' +for i, c in enumerate(s): + print(i, c) + +``` + + 0 P + 1 y + 2 t + 3 h + 4 o + 5 n + +```python +for i, v in enumerate(range(3)): + print(i, v) +``` + + 0 0 + 1 1 + 2 2 + +```python +L = ['ann', 'bob', 'joe', 'john', 'mike'] +for i, L in enumerate(L): + print(i, L) +``` + + 0 ann + 1 bob + 2 joe + 3 john + 4 mike + +```python +t = ('ann', 'bob', 'joe', 'john', 'mike') +for i, t in enumerate(t): + print(i, t) +``` + + 0 ann + 1 bob + 2 joe + 3 john + 4 mike + + +### 迭代前排序 + +可以用 `sorted()` 和 `reversed()` 在迭代前先排好序: + + +```python +t = ('bob', 'ann', 'john', 'mike', 'joe') +for i, t in enumerate(sorted(t)): + print(i, t) +``` + + 0 ann + 1 bob + 2 joe + 3 john + 4 mike + +```python +t = ('bob', 'ann', 'john', 'mike', 'joe') +for i, t in enumerate(sorted(t, reverse=True)): + print(i, t) +``` + + 0 mike + 1 john + 2 joe + 3 bob + 4 ann + +```python +t = ('bob', 'ann', 'john', 'mike', 'joe') +for i, t in enumerate(reversed(t)): + print(i, t) +``` + + 0 joe + 1 mike + 2 john + 3 ann + 4 bob + + +### 同时迭代多个容器 + +可以在 `zip()` 这个函数的帮助下,同时迭代两个或者两个以上的容器中的元素(这样做的前提是,多个容器中的元素数量最好相同): + + +```python +chars = 'abcdefghijklmnopqrstuvwxyz' +nums = range(1, 27) +for c, n in zip(chars, nums): + print(f"Let's assume {c} represents {n}.") +``` + + Let's assume a represents 1. + Let's assume b represents 2. + Let's assume c represents 3. + Let's assume d represents 4. + Let's assume e represents 5. + Let's assume f represents 6. + Let's assume g represents 7. + Let's assume h represents 8. + Let's assume i represents 9. + Let's assume j represents 10. + Let's assume k represents 11. + Let's assume l represents 12. + Let's assume m represents 13. + Let's assume n represents 14. + Let's assume o represents 15. + Let's assume p represents 16. + Let's assume q represents 17. + Let's assume r represents 18. + Let's assume s represents 19. + Let's assume t represents 20. + Let's assume u represents 21. + Let's assume v represents 22. + Let's assume w represents 23. + Let's assume x represents 24. + Let's assume y represents 25. + Let's assume z represents 26. + + +### 迭代字典中的元素 + + +```python +phonebook1 = {'ann':6575, 'bob':8982, 'joe':2598, 'zoe':1225, 'ann':6585} + +for key in phonebook1: + print(key, phonebook1[key]) +``` + + ann 6585 + bob 8982 + joe 2598 + zoe 1225 + +```python +phonebook1 = {'ann':6575, 'bob':8982, 'joe':2598, 'zoe':1225, 'ann':6585} + +for key, value in phonebook1.items(): + print(key, value) +``` + + ann 6585 + bob 8982 + joe 2598 + zoe 1225 +