第二十章 迭代和解析

#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

  

原文地址:https://www.cnblogs.com/szn409/p/6700971.html