#1.
#A:列表解析在一个序列的值上应用一个任意表达式,将其结果收集到一个新的列表中并返回
#B:map是一个迭代器,根据需求产生结果,同样为了节省内存,列表解析被编码成生成器表达式
def Fun(x) : return x ** 2
L0 = [1, 2, 3]
L1 = [x ** 2 for x in L0] #L1 = [1, 4, 9]
L2 = [Fun(x) for x in L0] #L2 = [1, 4, 9]
L3 = [(x , y) for x in L0 if x % 2 == 0 for y in L1 if y % 2 == 1] #L3 = [(2, 1), (2, 9)]
L4 = list(x ** 2 + 1 for x in L0) #L4 = [2, 5, 10]
#2.有两种语言会尽可能的延迟结果创建
#A:生成器函数:编写为常规的def语句,但是使用yieled语句一次返回一个结果,在每个结果之间挂起和继续他们的状态
#B:生成器表达式:每次按需产生结果的一个对象
#3.
#A:生成器函数和常规函数之间的主要代码不同之处在于,生成器yields(产生)一个值,而不是返回一个值,yield语句挂起该函数并向调用者发送一个值,但是保留足够的状态以使得函数能够从它离开的地方继续
#B:当继续时候,函数在上一个yield返回后立即继续执行,从函数角度来看,这允许其代码随时间产生一系列值,而不是一次计算它们并在诸如列表的内容中返回它们
#C:函数包含一条yield语句,该语句特别编译为生成器。当调用时,它们返回一个迭代器对象,支持__next__来进行自动创建。
#D:生成器函数也可能有一条return语句,总是在def语句块的末尾,直接终止值的生成
#E:生成器函数和生成器表达式自生都是迭代器,并只支持一次活跃的迭代,我们无法同时拥有位于不同位置的多个迭代器
def fun(n):
for i in range(n):
yield i ** 2
fun_3 = fun(3)
value = fun_3.__next__ #value = <method-wrapper '__next__' of generator object at 0x0000000002B0D558>
n0 = value() #n0 = 0
n1 = fun_3.__next__() #n1 = 1
n2 = fun_3.__next__() #n1 = 4
try:
n2 = fun_3.__next__()
except StopIteration:
pass #执行至此
fun_it0 = fun(3)
fun_it1 = fun(3)
b0 = iter(fun_3) is fun_3 #b0 = True
b1 = fun_it0 == fun_it1 #b1 = False
#4.
#A:从语法上讲,生成器表达式就像一般的列表解析一样,但是它们是括在圆括号中而不是方括号中,返回一个生成器对象,这个对象支持迭代
it= (x * 2 for x in 'szn')
L0 = []
for v in it:
L0.append(v) #L0 = ['ss', 'zz', 'nn']
#5.
#A:zip
L0 = list(zip("szn")) #L0 = [('s',), ('z',), ('n',)]
L0 = list(zip("szn", ())) #L0 = []
def myMap0(fun, *seqs):
res = []
for arg in zip(*seqs): #注意这里是*seqs而不是seqs,这里对seqs进行了解包
res.append(fun(*arg))
return res
def fun(x):
return x + ['szn']
L0 = myMap0(fun, [[1, 2, 3], [4, 5, 6, 7]]) #L0 = [[1, 2, 3, 'szn'], [4, 5, 6, 7, 'szn']]
L0 = myMap0(fun, [[1, 2, 3], [4, 5, 6, 7], [8]]) #L0 = L0 = [[1, 2, 3, 'szn'], [4, 5, 6, 7, 'szn'], [8, 'szn']]
L0 = myMap0(lambda x, y : x + y, [1, 2, 3], [4, 5, 6, 7]) #L0 = [5, 7, 9]
L0 = myMap0(lambda x : x + 1, [1, 2]) #L0 = [2, 3]
L0 = list(zip(*([1, 2, 3], [4, 5, 6, 7]))) #L0 = [(1, 4), (2, 5), (3, 6)]
L1 = list(zip(([1, 2, 3], [4, 5, 6, 7]))) #L1 = [([1, 2, 3],), ([4, 5, 6, 7],)]
def fun(v, v1):return v, v1
v = fun(*([1, 2, 3], [4, 5, 6, 7])) #v = ([1, 2, 3], [4, 5, 6, 7])
def myMap1(fun, *seqs):
return [fun(*args) for args in zip(*seqs)]
L0 = myMap1(lambda x, y : x + y, [1, 2, 3], [4, 5, 6, 7]) #L0 = [5, 7, 9]
def myMap2(fun, *seqs):
res = []
for args in zip(*seqs):
yield fun(*args)
L0 = list(myMap1(lambda x, y : x + y, [1, 2, 3], [4, 5, 6, 7])) #L0 = [5, 7, 9]
def myMap3(fun, *seqs):
return (fun(*args) for args in zip(*seqs))
L0 = list(myMap3(lambda x, y : x + y, [1, 2, 3], [4, 5, 6, 7])) #L0 = [5, 7, 9]
#6.
#A:
L0 = [1, 2, 3]
it = iter(L0)
it1 = iter(it)
bValue = it is it1 #bValue = True
list(it)
bValue = bool(it) #bValue = True
L1 = []
bValue = bool(iter(L1)) #bValue = True
def fun(args):
it = iter(args)
while 1:
value = it.__next__()
yield value
value = list(fun([1, 2, 3])) #value = [1, 2, 3]
#8.
#A:!!!!!!!!!!!!!!!!!待研究
def FunA(*args):
it = map(iter, args)
while 1:
it1 = it.__next__() #问题一:这里进行的迭代不会引发StopIterator异常吗
while 1:
try:
value = it1.__next__()
print("")
yield value
except:
break
value0 = list(FunA([1, 2], ['a', 'b', 'c'])) #value0 = [1, 2, 'a', 'b', 'c'] 问题二:为什么这里value0 = [1, 2, 'a', 'b', 'c']
def FunB(*args):
it = map(iter, args)
while 1:
it1 = it.__next__()
while 1:
value = it1.__next__()
print("")
yield value
value1 = list(FunB([1, 2], ['a', 'b', 'c'])) #value1 = [1, 2] 问题三:为什么这里value1 = [1, 2]
#9.!!!!!!!!!!!!!!!!!待研究
def myzipA(*args):
iters = list(map(iter, args))
while iters:
res = [next(i) for i in iters]
yield tuple(res)
value = list(myzipA('abc', 'efg')) #value = [('a', 'e'), ('b', 'f'), ('c', 'g')]
'''
def myzipB(*args):
iters = map(iter, args)
while iters:
res = [next(i) for i in iters]
yield tuple(res)
value = list(myzipB('abc', 'efg'))
'''
#10.
#A:time.time()返回1970年至今的秒计数
#B:time.clock()在Unix 中,将当前的处理器时间以浮点数的形式返回,单位为秒。它的精确度(准确地说是“处理器时间”的精确度)取决于同名的C函数,无论如何,这个函数是python关于时间计算的标尺。
# WINDOWS中,第一次调用,返回的是进程运行的实际时间。而第二次之后的调用是自第一次调用以后到现在的运行时间。(实际上是以WIN32上QueryPerformanceCounter()为基础,它比毫秒表示更为精确
#C:time.sleep()设置休眠的秒数
import time
t = time.time() #t = 1491912888.716247
t0 = time.clock()
time.sleep(1)
t1 = time.clock() - t0 #t1 = 0.9995179215014475
#11.
#A:
import sys
str = sys.platform #str = 'win32'
#12.
#A:函数陷阱
value = 10
def funA():
print(value) #运行到这里的时候会出错
value = 2
#产生上述错误的原因在于:被赋值的变量名在函数内部被当做本地变量对待,而不是仅仅在赋值以后的语句才被当做是本地变量,所以所执行的print语句中使用了未定义的本地变量名
def funB():
global value
print(value) #正常运行
value = 1 #全局变量value被更改了
def funC():
import __main__
list = dir(__main__) #list = ['Fun', 'FunA', 'FunB', 'L0', 'L1', 'L2', 'L3', 'L4', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', ...]
print(__main__.value) #输出的是全局变量value
value = 1 #不会修改全局变量value
#13
#A:模块是对象,并且所有的模块都有一个内置属性 __name__。一个模块的 __name__ 的值取决于您如何应用模块。如果 import 一个模块,那么模块__name__ 的值通常为模块文件名,
# 不带路径或者文件扩展名。但是您也可以像一个标准的程序样直接运行模块,在这种情况下, __name__ 的值将是一个特别缺省"__main__"
'''
Test.py内容:
def FunTest20():
return __name__
'''
import Test
str = Test.FunTest20() #str = 'Test'
str1 = __name__ #str1 = '__main__'
#14.
#A:默认参数是在def语句运行时评估并保存的,而不是在函数调用时。从内部讲,python会将每个默认参数保存成一个对象,附加在这个函数本身
valueTest = 10
def FunTest(value = []):
value.append(1)
return value
value0 = FunTest() #value0 = [1]
value1 = FunTest() #value1 = [1, 1]
bValue = value0 is value1 #bValue = True