流程控制

https://docs.python.org/zh-cn/3/tutorial/controlflow.html#more-control-flow-tools

if语句

  1. if x < 0:
  2. x = 0
  3. print('Negative changed to zero')
  4. elif x == 0:
  5. print('Zero')
  6. elif x == 1:
  7. print('Single')
  8. else:
  9. print('More')

for语句

遍历某个集合的同时修改该集合的内容,很难获取想要的结果。要在遍历时修改集合的内容,应该遍历该集合的副本或创建新的集合。
遍历拷贝对象

  1. # Strategy: Iterate over a copy
  2. users={"张三":'active',"李四":'inactive',"王五":'inactive'}
  3. for user,status in users.copy().items():
  4. if status == 'inactive':
  5. del users[user]
  6. print(users)

创建新的集合

  1. # Strategy: Create a new collection
  2. users={"张三":'active',"李四":'inactive',"王五":'inactive'}
  3. active_users = {}
  4. for user, status in users.items():
  5. if status == 'active':
  6. active_users[user] = status
  7. print(active_users)

range函数

用于控制循环次数

  1. # 执行循环5次
  2. for i in range(5):
  3. print(i)

生成等差数列(列表)

  1. list(range(5, 10)) # 默认公差为1
  2. # [5, 6, 7, 8, 9]
  3. list(range(0, 10, 3)) # 公差为3
  4. # [0, 3, 6, 9]
  5. list(range(-10, -100, -30)) # 公差为-30

按索引进行循环

  1. a = ['Mary', 'had', 'a', 'little', 'lamb']
  2. for i in range(len(a)):
  3. print(i, a[i])

注意:range()的返回值为一个可迭代对象,而不是一组数字。range() 返回对象的操作和列表很像,但其实这两种对象不是一回事。迭代时,该对象基于所需序列返回连续项,并没有生成真正的列表,从而节省了空间

for-else语句

for循环中正常结束时则会执行else语句中的内容,未能正常结束(如break)则不执行

  1. # 该语句中若执行到了break,则else语句不会执行。
  2. for n in range(2, 10):
  3. for x in range(2, n):
  4. if n % x == 0:
  5. print(n, 'equals', x, '*', n//x)
  6. break
  7. else:
  8. print(n, 'is a prime number')

pass语句

pass 语句不执行任何操作。语法上需要一个语句,但程序不实际执行任何动作时,可以使用该语句。如空循环,空类,占位符。

函数

无返回值的函数将返回 None

默认参数

  1. def ask_ok(prompt, retries=4, reminder='Please try again!'):
  2. while True:
  3. ok = input(prompt)
  4. if ok in ('y', 'ye', 'yes'):
  5. return True
  6. if ok in ('n', 'no', 'nop', 'nope'):
  7. return False
  8. retries = retries - 1
  9. if retries < 0:
  10. raise ValueError('invalid user response')
  11. print(reminder)

重要警告: 默认值只计算一次。默认值为列表、字典或类实例等可变对象时,会产生与该规则不同的结果。例如,下面的函数会累积后续调用时传递的参数:

  1. def f(a, L=[]):
  2. L.append(a)
  3. return L
  4. print(f(1))
  5. print(f(2))
  6. print(f(3))
  7. """
  8. [1]
  9. [1, 2]
  10. [1, 2, 3]
  11. """
  12. # 正确用法:
  13. def f(a, L=None):
  14. if L is None:
  15. L = []
  16. L.append(a)
  17. return L

关键词参数

可以通过kwarg=value形式的关键字参数调用函数。

  1. def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
  2. print("-- This parrot wouldn't", action, end=' ')
  3. print("if you put", voltage, "volts through it.")
  4. print("-- Lovely plumage, the", type)
  5. print("-- It's", state, "!")
  6. parrot(1000) # 1 positional argument
  7. parrot(voltage=1000) # 1 keyword argument
  8. parrot(voltage=1000000, action='VOOOOOM') # 2 keyword arguments
  9. parrot(action='VOOOOOM', voltage=1000000) # 2 keyword arguments
  10. parrot('a million', 'bereft of life', 'jump') # 3 positional arguments
  11. parrot('a thousand', state='pushing up the daisies') # 1 positional, 1 keyword

接受元组和字典

最后一个形参为 name 形式时,接收一个字典(详见 映射类型 —- dict),该字典包含与函数中已定义形参对应之外的所有关键字参数。name 形参可以与 name 形参(下一小节介绍)组合使用(name 必须在 *name 前面), name 形参接收一个 元组,该元组包含形参列表之外的位置参数。例如,可以定义下面这样的函数:

  1. def cheeseshop(kind, *arguments, **keywords):
  2. print("-- Do you have any", kind, "?")
  3. print("-- I'm sorry, we're all out of", kind)
  4. # print(type(arguments)) #<class 'tuple'>
  5. for arg in arguments:
  6. print(arg)
  7. print("-" * 40)
  8. #print(type(keywords)) #<class 'dict'>
  9. for kw in keywords:
  10. print(kw, ":", keywords[kw])
  11. cheeseshop("Limburger", "It's very runny, sir.",
  12. "It's really very, VERY runny, sir.",
  13. shopkeeper="Michael Palin",
  14. client="John Cleese",
  15. sketch="Cheese Shop Sketch")

位置参数和关键词参数

使用”/“和”“来限制参数传递的方式是位置传递或者关键词参数,”/“前的是位置参数,不可以通过关键词方式传参,后为关键词参数,不可以通过位置参数传递。

  1. def combined_example(pos_only, /, standard, *, kwd_only):
  2. print(pos_only, standard, kwd_only)
  3. combined_example(1, 2, kwd_only=3)

可变参数

使用或者*传入元组或者字典达到可变参数的效果。

  1. def concat(*args, sep="/"): ## 传入元组
  2. return sep.join(args)
  3. print(concat("earth", "mars", "venus"))

参数传递-容器展开

  1. # 列表展开 作为位置参数
  2. args = [3, 6]
  3. print(*args)
  4. # 字典展开 作为关键词参数
  5. def parrot(voltage, state='a stiff', action='voom'):
  6. print("-- This parrot wouldn't", action, end=' ')
  7. print("if you put", voltage, "volts through it.", end=' ')
  8. print("E's", state, "!")
  9. d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
  10. parrot(**d)

lambda表达式

  1. pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]
  2. pairs.sort(key=lambda pair: pair[1])
  3. print(pairs)

数据结构

https://docs.python.org/zh-cn/3/tutorial/datastructures.html#data-structures

列表

列表常用操作

  1. list.append(x)
  2. 在列表末尾添加一个元素,相当于 a[len(a):] = [x]
  3. list.extend(iterable)
  4. 用可迭代对象的元素扩展列表。相当于 a[len(a):] = iterable
  5. list.insert(i, x)
  6. 在指定位置插入元素。第一个参数是插入元素的索引,因此,a.insert(0, x) 在列表开头插入元素,
  7. a.insert(len(a), x) 等同于 a.append(x)
  8. list.remove(x)
  9. 从列表中删除第一个值为 x 的元素。未找到指定元素时,触发 ValueError 异常。
  10. list.pop([i])
  11. 删除列表中指定位置的元素,并返回被删除的元素。未指定位置时,a.pop() 删除并返回列表的最后一个元素。
  12. (方法签名中 i 两边的方括号表示该参数是可选的,不是要求输入方括号。这种表示法常见于 Python 参考库)。
  13. list.clear()
  14. 删除列表里的所有元素,相当于 del a[:]
  15. list.index(x[, start[, end]])
  16. 返回列表中第一个值为 x 的元素的零基索引。未找到指定元素时,触发 ValueError 异常。
  17. 可选参数 start end 是切片符号,用于将搜索限制为列表的特定子序列。
  18. 返回的索引是相对于整个序列的开始计算的,而不是 start 参数。
  19. list.count(x)
  20. 返回列表中元素 x 出现的次数。
  21. list.sort(*, key=None, reverse=False)
  22. 就地排序列表中的元素(要了解自定义排序参数,详见 sorted())。
  23. list.reverse()
  24. 反转列表中的元素。
  25. list.copy()
  26. 返回列表的浅拷贝。相当于 a[:]
  1. fruits = ['orange', 'apple', 'pear', 'banana', 'kiwi', 'apple', 'banana']
  2. ret=fruits.count('apple')
  3. print(ret)
  4. ret=fruits.index('banana')
  5. print(ret)
  6. ret=fruits.index('banana', 4) # Find next banana starting a position 4
  7. print(ret)
  8. fruits.reverse()
  9. print(fruits)
  10. fruits.append('grape')
  11. print(fruits)
  12. fruits.sort()
  13. print(fruits)
  14. ret=fruits.pop()
  15. print(ret)

列表推导式

列表推导式创建列表的方式更简洁。常见的用法为,对序列或可迭代对象中的每个元素应用某种操作,用生成的结果创建新的列表;或用满足特定条件的元素创建子序列。
列表推导式的方括号内包含以下内容:一个表达式,后面为一个 for 子句,然后,是零个或多个 for 或 if 子句。结果是由表达式依据 for 和 if 子句求值计算而得出一个新列表。

  1. squares = [x**2 for x in range(10)]
  2. [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]

嵌套的列表推导式

  1. matrix = [
  2. [1, 2, 3, 4],
  3. [5, 6, 7, 8],
  4. [9, 10, 11, 12],
  5. ]
  6. # 矩阵转置
  7. ret= [[row[i] for row in matrix] for i in range(4)]
  8. print(ret)
  9. # [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

del语句

删除列表中元素
del语句作用在变量上,而不是数据对象上。

  1. a = [-1, 1, 66.25, 333, 333, 1234.5]
  2. first = a[0]
  3. del a[0]
  4. print(a) # [1, 66.25, 333, 333, 1234.5]
  5. print(first) # -1
  1. if __name__=='__main__':
  2. a=1 # 对象 1 被 变量a引用,对象1的引用计数器为1
  3. b=a # 对象1 被变量b引用,对象1的引用计数器加1
  4. c=a #1对象1 被变量c引用,对象1的引用计数器加1
  5. del a #删除变量a,解除a对1的引用
  6. del b #删除变量b,解除b对1的引用
  7. print(c) #最终变量c仍然引用1
  8. if __name__=='__main__':
  9. li=[1,2,3,4,5] #列表本身不包含数据1,2,3,4,5,而是包含变量:li[0] li[1] li[2] li[3] li[4]
  10. first=li[0] #拷贝列表,也不会有数据对象的复制,而是创建新的变量引用
  11. del li[0]
  12. print(li) #输出[2, 3, 4, 5]
  13. print(first) #输出 1

元组

https://docs.python.org/zh-cn/3/tutorial/datastructures.html#tuples-and-sequences

  • 声明一个元组,声明元组可以不使用圆括号,当元组嵌套时,建议使用圆括号。

    1. t = 12345, 54321, 'hello!'
    2. t[0] #12345
    3. t #(12345, 54321, 'hello!')
  • 元组可以嵌套

    1. # Tuples may be nested:
    2. u = t, (1, 2, 3, 4, 5)
    3. u #((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))
  • 元组内容是不可变的

    1. # Tuples are immutable:
    2. t[0] = 88888
    3. Traceback (most recent call last):
    4. File "<stdin>", line 1, in <module>
    5. TypeError: 'tuple' object does not support item assignment
  • 元组中可以存放内容可变对象(如列表)

    1. v = ([1, 2, 3], [3, 2, 1])
    2. v[0][1] = 3
    3. print(v) #([1, 3, 3], [3, 2, 1])
  • 空元组和单元素元组 ```python

    空元组

    empty = () print(empty,type(empty)) # ()

singleton = 10, print(singleton,type(singleton)) #(10,)

tmp = (10) print(tmp,type(tmp)) #10

  1. - 元组打包和解包
  2. ```python
  3. t = 12345, 54321, 'hello!' #元组打包
  4. a,b,c = t # 元组解包
  5. x,y,z = "a","b","c" #多重复制 为元组打包和解包

集合

集合是由不重复元素组成的无序容器。基本用法包括成员检测、消除重复元素。集合对象支持合集、交集、差集、对称差分等数学运算。
创建
空集合只能用set()方法创建,直接使用{}会创建空字典。

  1. basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}

集合运算

  1. basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
  2. ## 集合去重
  3. print(basket) #{'banana', 'pear', 'orange', 'apple'}
  4. ## 集合测试元素存在
  5. print('apple' in basket) # True
  6. ## 集合关系运算
  7. a=set("abcdedg") # 注意a为字符集合长度为7 而a={"abcdedg"} 则只有1个元素
  8. print(a)
  9. b = set('alacazam')
  10. print(b)
  11. # 交运算
  12. print(a & b) # {'c', 'a'}
  13. # 并运算
  14. print( a | b) # {'b', 'z', 'l', 'g', 'e', 'a', 'm', 'c', 'd'}
  15. # 差运算
  16. print(a-b) # {'e', 'g', 'b', 'd'}
  17. # 对称差分
  18. print(a^b) # {'z', 'b', 'g', 'e', 'm', 'l', 'd'}

字典

字典以关键字为索引,关键字通常是字符串或数字,也可以是其他任意不可变类型。只包含字符串、数字、元组的元组,也可以用作关键字。但如果元组直接或间接地包含了可变对象,就不能用作关键字。列表不能当关键字,因为列表可以用索引、切片、append() 、extend() 等方法修改。

  1. ## 创建空字典
  2. m = {}
  3. ## dict() 构造函数构造 直接用键值对序列创建字典
  4. print(dict([('sape', 4139), ('guido', 4127), ('jack', 4098)]))
  5. ## dict() 直接用关键字参数指定键值d对
  6. print(dict(sape=4139, guido=4127, jack=4098))
  7. ## 列表推导创建字典
  8. tmp = {x: x**2 for x in (2, 4, 6)}
  9. print(type(tmp)) # <class 'dict'>
  10. ## 增加元素
  11. m["hello"] = 100
  12. print(m) #{'hello': 100}
  13. ## 修改
  14. m["hello"]=10 #{'hello': 10}
  15. print(m)
  16. ## 删除元素
  17. del m["hello"]
  18. print(m) #{}
  19. ## 判断存在
  20. m["hello"]=0
  21. print("hello" in m) #True
  22. ## 转为列表
  23. m["world"]=0
  24. print(list(m)) #['hello', 'world']
  25. ## 排序 默认对索引值排序
  26. print(sorted(m)) #['hello', 'world']

字典按元素值排序:

  1. import operator
  2. classCount={1:23,2:43,3:43,4:3}
  3. sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
  4. sortedClassCount
  5. # [(2, 43), (3, 43), (1, 23), (4, 3)]

遍历

字典遍历

  • 在字典中循环时,用 items() 方法可同时取出键和对应的值 。
    1. knights = {'gallahad': 'the pure', 'robin': 'the brave'}
    2. for k, v in knights.items():
    3. print(k,"-",v)

    列表遍历

    序列中循环时,用 enumerate() 函数可以同时取出位置索引和对应的值。
    1. for i, v in enumerate(['tic', 'tac', 'toe']):
    2. print(i, v)
    同时循环两个或多个序列时,用 zip() 函数可以将其内的元素一一匹配。
    1. questions = ['name', 'quest', 'favorite color']
    2. answers = ['lancelot', 'the holy grail', 'blue']
    3. for q, a in zip(questions, answers):
    4. print('What is your {0}? It is {1}.'.format(q, a))
    使用集合构造函数set()和sorted函数 遍历列表中的唯一元素
    1. basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
    2. for f in sorted(set(basket)):
    3. print(f)

    map函数

    https://www.runoob.com/python/python-func-map.html
    map() 会根据提供的函数对指定序列做映射。
    第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表