迭代器和生成器

for element in [1, 2, 3]:
print(element)
for element in (1, 2, 3):
print(element)
for key in {'one':1, 'two':2}:
print(key)
for char in "123":
print(char)
for line in open("myfile.txt"):
print(line, end='')

我们之所以能通过 for 方法如此轻松的打印这些内容,从本质上说是因为列表元组等这些东西是一个可迭代对象。而 for 方法则可以调用迭代器对象的方法来实现对整个迭代对象的遍历。for 驱动可迭代对象调用 iter()返回了一个有next()方法的迭代器对象(可以通过 next()访问),该方法可以逐一访问对象中的所有元素。
image.png
生成器则是用来为迭代器产生数据的,写法类似于标准的函数,但当他们要返回数据时要使用 yield 函数,每次迭代生成器时,它会从上次离开的位置恢复执行(它会记住上次执行语句时的所有数据值)。 一个显示如何非常容易地创建生成器的示例如下:

def reverse(data):
for index in range(len(data)-1, -1, -1):
yield data[index]
for char in reverse('golf'):
print(char)

python 语句

if

if 语句简写

if condition:
x=1
else:
x=2
#可简写为x=1 if condition else 2

使用 while 循环

  • 使用 break 跳出循环
  • 使用 continue 跳到循环开始
  • 循环外使用 else:用来判断循环是否正常结束。如果 while 循环内的 break 没有被执行,会自动执行 else 内的语句,否则则不会。
a=int(input("请输入一个整数:"))
num=a
while a:
if a%3==0:
break
a-=1
else:
print("没有比%d小的3的倍数"%num)
# 可简写为

使用 for 迭代

  • break 跳出循环
  • continue 跳到循环开始
  • else:与 while 相似,用来判断循环是否正常结束
  • 使用 zip()进行并行迭代
  • 使用 range()生成自然数列
  • 其他迭代方法

zip range 函数返回的都是一个可迭代的对象,因此可以使用 for ……in 的结构遍历。

zip 函数

在我们进行多变量循环时,有时会用到非嵌套的多个变量的循环,这时可以借助zip()函数(多个序列的迭代)。以一种更简单的方式实现匹配!

zip(iterable1,iterable2,…)

其中 iterable 接收字符串、列表、元组、字典。该函数将多个等长的 iterable 可迭代对象压缩为元组。zip 函数会在最短序列用完时停止迭代。可使用 list()访问压缩结果。

kernels=['linear', 'poly', 'rbf','sigmoid']
figNum=[1,2,3,4]
print('kernels=',kernels)
print('figNum=',figNum)
zipped=zip(kernels,figNum)
print('zip(kernels,figNum)=',list(zipped))

异常处理–try,except

在我们的代码运行过程中,我们的程序可能会因为输入数据不符合要求等各种情况导致程序直接运行停止。针对这种情况,python 程序设计了一种 try,except 语句来辅助我们进行对可能出现的异常情况进行处理:

try:
#这里写测试语句,即有可能导致出现异常情况的依据
except 异常名称,异常数据:
#对异常数据的处理方法
#非必选项
else:
#未出现异常语句时要执行的语句
finally:
#不管有没有异常都需要执行的语句

python3 可能出现的标准异常情况有很多:
image.png
image.png

#创建一个任意长度的列表并求取列表中任意位置的值
from turtle import numinput
n=int(input("请输入列表的总长度n:"))
numlist=[]
while len(numlist)<n:
try:
intnumber=int(input("请输入列表中的第%d个数字:"%(len(numlist)+1)))
except ValueError:
print("输入的数字有误,请重新输入:")
continue
numlist.append(intnumber)
print("您输入的列表为:",numlist)
while 1:
inputstr=input("请输入您要查询的列表中的元素位置")
try:
index=int(inputstr)
except ValueError:
print("您输入的下标不是整数,请重新输入")
continue
try:
outnum=numlist[index]
except IndexError:
print("您输入的下标太大,请重新输入:")
continue
break
print(outnum)

有时我们可能期望获取异常的具体情况,这时可以选择利用 as 将异常情况赋予某一变量:

image.png

推导式

推导式是从一个或者多个迭代器快速简洁地创建数据结构的一种方法。

expression for item in iterable if condition
#创建一个1-5的列表
print([i for i in range(1,6)])
print(list(range(1,6)))

与上述例子类似,我们也可以创建字典推导式:

key_expression:value_expression for expression in iterable
inputstring=input("Please enter a word:")
letter_counts={letter:word.count(letter) for letter in inputstring}
#避免重复计算,进行进一步优化
letter_counts={letter:word.count(letter) for letter in set(inputstring)}

类似地还可以建立集合的推导式(列表的生成式用’[]’,元组用’{}’,字典解析式也是用’{}'不过要表示成键值对的形式),但需要注意的是元组是没有推导式的,返回的是一个生成器对象。因为两个括号有另外的含义,它会生成一个生成器

string = "Words are but wind"
word_order = {el: ind+1 for ind, el in enumerate(string.split())}
print(word_order)

image.png

嵌套

cities = ['New York', 'Oklahoma', 'Toronto', 'Los Angeles', 'Miami']
budgets = {city: [0 for x in range(12)] for city in cities}
print(budgets)
#展平矩阵
matrix = [
[0, 1, 0],
[1, 0, 1],
[2, 1, 2],
]
flat = [num for row in matrix for num in row]
print(flat)

生成器表达式

某些简单的生成器可以写成简洁的表达式代码,所用语法类似列表推导式,但外层为圆括号而非方括号。 这种表达式被设计用于生成器将立即被外层函数所使用的情况。 生成器表达式相比完整的生成器更紧凑但较不灵活,相比等效的列表推导式则更为节省内存

>>> sum(i*i for i in range(10))                 # sum of squares
285

>>> xvec = [10, 20, 30]
>>> yvec = [7, 5, 3]
>>> sum(x*y for x,y in zip(xvec, yvec)) # dot product
260

>>> unique_words = set(word for line in page for word in line.split())

>>> valedictorian = max((student.gpa, student.name) for student in graduates)

>>> data = 'golf'
>>> list(data[i] for i in range(len(data)-1, -1, -1))
['f', 'l', 'o', 'g']

Python 中的列表表达式通过将整个列表存储到内存中来工作。对于小型至中型列表这通常很好。当数据量较大时,列表表达式可能就不能工作了,这个时候可以考虑生成器

summary = sum((x for x in range(1000000000)))
print(summary)
import timeit


def get_sum_with_map():
return sum(map(lambda x: x, range(1000000000)))


def get_sum_with_generator():
return sum((x for x in range(1000000000)))


print(timeit.timeit(get_sum_with_map, number=100))
print(timeit.timeit(get_sum_with_generator, number=100))

生成器效率比map()高得多。

装饰器

装饰器实质上是一个函数,它把一个函数作为输入并且返回另外一个函数。一般用于修改已经存在的函数。实际使用过程中我们只需在需要装饰的函数前加上"@decorator_name "即可。

def test(func):
print("start")
def new_fun(*args,**kwargs):
result=func(*args,**kwargs)
print("end")
return result
return new_fun
@test
def f(a,b):
print(a+b)
f(1,2)
def test(func):
print("我不知道函数的具体内容,但我依然可以对函数进行修饰")
return func

@test
def add(a,b):
return a+b
print(add(1,2))


#人工赋值方法
#add1=test(add)

一个函数可以有多个装饰器,靠近函数定义的装饰器最先被执行,然后依次上面的。

读写文件

文本格式化(变量插值到字符串中)

Python 格式化方法有两种分别是旧式格式化方法(使用%格式化)和新的格式化方法(使用{}格式化)

%的格式化方法

一般情况下,使用这种格式化方法的格式为:
print("Just give an example %ab.cd"%(Var_name))

  • a:代表排版符号,表示打印字符串的排版方式,左对齐或者右对齐,此处写一个"-"表示左对齐
  • b:代表域宽表示符,即变量打印结果所占最小长度,默认用空格补齐。该处值可为零,表示自动分配
  • c:字符宽度限定值,若输入字符串过长则会自动截断。
  • d:输出变量结果的格式。“d”,“s”,"f"等

另外,域宽和字符宽度等设定也可以作为参数传入:
image.png

{}和 format 的新式格式化方法

新式格式化方法用{}来限定格式化字符串的输出格式,与%ab.cd 的表示方法相似但又有一定的区别:
print("Just give an example {x:hab.c}"%(Var_name))

  • x:可以为数字也可以为变量名称,若为数字表示参数传入的顺序(可以自己指定插入变量的顺序)若为变量名称则为 format()中传入的变量的名称(此时变量需要写成函数定义中关键词变量的声明方式)
  • h:仍是排版符号。">“表示右对齐,”<“表示左对齐,”^"居中对齐
  • a:宽度标识符,限制最小域宽度
  • b:填充字符,表示在输入字符串小于最小域宽度时自动填充的字符

另外需要注意的是跟老式格式化方法不同的是新式不需要指定格式化变量的类型,也就是说输入的格式化变量可以为任何类型,我们可以将字典类输入到变量中去,然后借助形如x[]:hab.c的形式进行索引:
image.png

排版符号,宽度标识符,填充字符