学习python--第五天

全局变量与局部变量两者的本质区别就是在于作用域

    用通俗的话来理解的话,

    全局变量是在整个py文件中声明,全局范围内都可以访问

    局部变量是在某个函数中声明的,只能在该函数中调用它,如果试图在超出范围的地方调用,程序就爆掉了

    Python中有局部变量和全局变量,当局部变量名字和全局变量名字重复时,局部变量会覆盖掉全局变量

  •  如果要给全局变量在一个函数里赋值,必须使用global语句
    name='牛逼哄哄'
    def change_name():
        # global name
        name='帅了一比'
        print('change_name',name)
    change_name()
    print(name)
    
    输出结果:
    change_name 帅了一比
    牛逼哄哄
    

     

  • python前向引用 (即函数调用在函数定义之前)

# def foo():
#     print('from foo')
#     bar()
#
# foo()

# def bar():
#     print('from bar')
# def foo():
#     print('from foo')
#     bar()
#
# foo()



# def foo():
#     print('from foo')
#     bar()
#
# def bar():
#     print('from bar')
# foo()

def foo():
    print('from foo')
    bar()

foo()

def bar():
    print('from bar')
输出结果会报错
  •  匿名函数

匿名函数就是没有实际名称的函数。其主体仅仅是一个表达式,而不需要使用代码块。

<函数对象名> = lambda   <形式参数列表>:<表达式>

 

例如:

def add(x,y):

         return x+y

可定义为匿名函数:  func=lambda x,y:x+y

 

 

为什么要使用lambda?

1、lambda函数主要用来写一些小体量的一次性函数,避免污染环境,同时也能简化代码。

2、lambda起到了一种函数速写的作用,允许在使用的代码内嵌入一个函数的定义。他们完全是可选的(你总是能够使用def来替代它们),但是你仅需要嵌入小段可执行代码的情况下它们会带来一个更简洁的代码结构。

例如:

map( lambda x: x*x, [y for y in range(10)] )

这个写法要好过

def sq(x):

return x * x

map(sq, [y for y in range(10)])
  •  map函数

描述

map() 会根据提供的函数对指定序列做映射。

第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表。

语法

map() 函数语法:

map(function, iterable, ...)

参数

  • function -- 函数
  • iterable -- 一个或多个序列

返回值

Python 2.x 返回列表。

Python 3.x 返回迭代器。

以下实例展示了 map() 的使用方法:
>>>def square(x) :            # 计算平方数
...     return x ** 2
... 
>>> map(square, [1,2,3,4,5])   # 计算列表各个元素的平方
[1, 4, 9, 16, 25]
>>> map(lambda x: x ** 2, [1, 2, 3, 4, 5])  # 使用 lambda 匿名函数
[1, 4, 9, 16, 25]
 
# 提供了两个列表,对相同位置的列表数据进行相加
>>> map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])
[3, 7, 11, 15, 19]

 

num_l=[1,2,10,5,3,7]
num_2=[1,2,10,5,3,8]
def add_one(x):
    return x+1

def reduce_one(x):
    return x-1

def map_test(func,array):
    rep=[]
    for i in array:
        res=func(i)
        rep.append(res)
    return rep
test1=map_test(add_one,num_l)
test2=map_test(reduce_one,num_2)
print(test1)
print(test2)

输出结果:
[2, 3, 11, 6, 4, 8]
[0, 1, 9, 4, 2, 7]

**********************************
用map函数来处理
test1=list(map(add_one,num_l))
test1=list(map(reduce_one,num_2))
可以省略掉 def map_test的定义,该函数的方法已经在map函数里面实现了
  •  filter函数

描述

filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回一个迭代器对象,如果要转换为列表,可以使用 list() 来转换。

该接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判,然后返回 True 或 False,最后将返回 True 的元素放到新列表中。

语法

以下是 filter() 方法的语法:

filter(function, iterable)

参数

  • function -- 判断函数。
  • iterable -- 可迭代对象。

返回值

返回一个迭代器对象

过滤出列表中的所有奇数:
#!/usr/bin/python3
 
def is_odd(n):
    return n % 2 == 1
 
tmplist = filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
newlist = list(tmplist)
print(newlist)

输出结果 :

[1, 3, 5, 7, 9]

 

movie_people=['alex_sb','wupeiqi_sb','linhaifeng','yuanhao_sb']
def filter_test(func,array):
    ret=[]
    for p in array:
        if not func(p):
               ret.append(p)
    return ret

res=filter_test(lambda n:n.endswith('sb'),movie_people)
print(res)

输出结果:
['linhaifeng']

等于用filter函数:
movie_people=['alex_sb','wupeiqi_sb','linhaifeng','yuanhao_sb']
res=list(filter(lambda n:not n.endswith('sb'),movie_people))
print(res)

输出结果:
['linhaifeng']

 

  • reduce函数

描述

reduce() 函数会对参数序列中元素进行累积。

函数将一个数据集合(链表,元组等)中的所有数据进行下列操作:用传给 reduce 中的函数 function(有两个参数)先对集合中的第 1、2 个元素进行操作,得到的结果再与第三个数据用 function 函数运算,最后得到一个结果。

语法

reduce() 函数语法:

reduce(function, iterable[, initializer])

参数

  • function -- 函数,有两个参数
  • iterable -- 可迭代对象
  • initializer -- 可选,初始参数

返回值

返回函数计算结果。

from functools import reduce #在python3必须加这一行才能使用reduce,在python2可以直接使用
def add(x, y) :            # 两数相加
    return x + y

print(reduce(add, [1,2,3,4,5]))
print(reduce(lambda x, y: x+y, [1,2,3,4,5]))  # 使用 lambda 匿名函数

输出结果:
15
15

 

num_l=[1,2,3,100]
def reduce_test(func,array,init=None):
    if init is None:
        res=array.pop(0)
    else:
        res=init
    for num in array:
        res=func(res,num)
    return res

print(reduce_test(lambda x,y:x*y,num_l,100))

等同于
#reduce函数
from functools import reduce
num_l=[1,2,3,100]
#print(reduce(lambda x,y:x+y,num_l,1))
#print(reduce(lambda x,y:x+y,num_l))
print(reduce(lambda x,y:x*y,num_l,100))

  •  map、filter、reduce
#处理序列中的每个元素,得到的结果是一个‘列表’,该‘列表’元素个数及位置与原来一样
# map()

#filter遍历序列中的每个元素,判断每个元素得到布尔值,如果是True则留下来

people=[
    {'name':'alex','age':1000},
    {'name':'wupei','age':10000},
    {'name':'yuanhao','age':9000},
    {'name':'linhaifeng','age':18},
]
print(list(filter(lambda p:p['age']<=18,people)))


#reduce:处理一个序列,然后把序列进行合并操作
from functools import reduce
print(reduce(lambda x,y:x+y,range(100),100))
print(reduce(lambda x,y:x+y,range(1,101)))
  •  0、空、none 的布尔值是false
  • all函数

描述

all() 函数用于判断给定的可迭代参数 iterable 中的所有元素是否都为 TRUE,如果是返回 True,否则返回 False。

元素除了是 0、空、FALSE 外都算 TRUE。

函数等价于:

def all(iterable):
    for element in iterable:
        if not element:
            return False
    return True

Python 2.5 以上版本可用。

语法

以下是 all() 方法的语法:

all(iterable)

参数

  • iterable -- 元组或列表。

返回值

如果iterable的所有元素不为0、''、False或者iterable为空,all(iterable)返回True,否则返回False;

注意:空元组、空列表返回值为True,这里要特别注意。

实例

以下展示了使用 all() 方法的实例:
>>>all(['a', 'b', 'c', 'd'])  # 列表list,元素都不为空或0
True
>>> all(['a', 'b', '', 'd'])   # 列表list,存在一个为空的元素
False
>>> all([0, 1,2, 3])          # 列表list,存在一个为0的元素
False
   
>>> all(('a', 'b', 'c', 'd'))  # 元组tuple,元素都不为空或0
True
>>> all(('a', 'b', '', 'd'))   # 元组tuple,存在一个为空的元素
False
>>> all((0, 1, 2, 3))          # 元组tuple,存在一个为0的元素
False
   
>>> all([])             # 空列表
True
>>> all(())             # 空元组
True
  •  any函数

描述

any() 函数用于判断给定的可迭代参数 iterable 是否全部为 False,则返回 False如果有一个为 True,则返回 True

元素除了是 0、空、FALSE 外都算 TRUE

函数等价于:

def any(iterable):
    for element in iterable:
        if element:
            return True
    return False

Python 2.5 以上版本可用。

语法

以下是 any() 方法的语法:

any(iterable)

参数

  • iterable -- 元组或列表。

返回值

如果都为空、0、false,则返回false,如果不都为空、0、false,则返回true。

实例

以下展示了使用 any() 方法的实例:
>>>any(['a', 'b', 'c', 'd'])  # 列表list,元素都不为空或0
True
 
>>> any(['a', 'b', '', 'd'])   # 列表list,存在一个为空的元素
True
 
>>> any([0, '', False])        # 列表list,元素全为0,'',false
False
 
>>> any(('a', 'b', 'c', 'd'))  # 元组tuple,元素都不为空或0
True
 
>>> any(('a', 'b', '', 'd'))   # 元组tuple,存在一个为空的元素
True
 
>>> any((0, '', False))        # 元组tuple,元素全为0,'',false
False
  
>>> any([]) # 空列表
False
 
>>> any(()) # 空元组
False
  •  divmod函数

python divmod() 函数把除数和余数运算结果结合起来,返回一个包含商和余数的元组(a // b, a % b)。

在 python 2.3 版本之前不允许处理复数。

函数语法

divmod(a, b)

参数说明:

  • a: 数字
  • b: 数字  
实例
>>>divmod(7, 2)
(3, 1)
>>> divmod(8, 2)
(4, 0)
>>> divmod(1+2j,1+0.5j)
((1+0j), 1.5j)
  •  eval函数

描述

eval() 函数用来执行一个字符串表达式,并返回表达式的值。

语法

以下是 eval() 方法的语法:

eval(expression[, globals[, locals]])

参数

  • expression -- 表达式。
  • globals -- 变量作用域,全局命名空间,如果被提供,则必须是一个字典对象。
  • locals -- 变量作用域,局部命名空间,如果被提供,可以是任何映射对象。

返回值

返回表达式计算结果。

 以下展示了使用 eval() 方法的实例:
>>>x = 7
>>> eval( '3 * x' )
21
>>> eval('pow(2,2)')
4
>>> eval('2 + 2')
4
>>> n=81
>>> eval("n + 4")
85
  •  enumerate函数

描述

enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。

语法

以下是 enumerate() 方法的语法:

enumerate(sequence, [start=0])

参数

  • sequence -- 一个序列、迭代器或其他支持迭代对象。
  • start -- 下标起始位置。

返回值

返回 enumerate(枚举) 对象。

 以下展示了使用 enumerate() 方法的实例:
>>>seasons = ['Spring', 'Summer', 'Fall', 'Winter']
>>>list(enumerate(seasons))
[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
>>>list(enumerate(seasons, start=1))       # 小标从 1 开始
[(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]

 

list=["one","two","three"]
for i in range (len(list)):
    print(i)
    print(list[i])

输出结果:
0
one
1
two
2
three

等于用enumerate函数
list=["one","two","three"]
for index,item in enumerate(list):
    print(index,item)

输出结果:
0 one
1 two
2 three

等于用enumerate函数
list=["one","two","three"]
for index,item in enumerate(list,1):   #序号从1开始,不写的话默认是0开始
    print(index,item)
输出结果:
1 one
2 two
3 three

 

1、第一个实例,打印输出索引与value值

 1 >>> product = [
 2 ...         "Mac pro",
 3 ...         "iPhone",
 4 ...         "iWatch"
 5 ...     ]
 6 >>> for index,item in enumerate(product):
 7 …          print(index,item)
 8 >>>
 9 
10 得到以下结果 
11 0     Mac pro
12 1    iPhone
13 2    iWatch

14 也可以使用enumerate函数的第二个参数:

15 >>> for index,item in enumerate(product,1)://第二个参数表示下标开始的位置,取值为1即表示下标从1开始计算,默认从0开始
16  …          print(index,item)
17 >>>
18 得到以下结果
19 1  Mac pro
20 2   iPhone
21 3   iWatch

复制代码
复制代码

2、第二个实例
复制代码

#列表
product = ["Mac pro", "iPhone", "iWatch"]
for index, item in enumerate(product):
    print(index, item)
    
#列表
list = [1, 2, 3, 4, 5, 6]
list[::-1]
for index, item in enumerate(list):
    print(index, item)

#字符串
for i, j in enumerate('abcde'):
    print(i, j)
    
#数组
for i, j in enumerate(('a', 'b', 'c', 'd', 'e')):
    print(i, j)

#字典
for i, j in enumerate({'a':1, 'b':2}):
    print(i, j)

复制代码

3、第三个实例:统计文件的行数
复制代码

#如果要统计文件的行数,可以这样写:
count = len(open(filepath, 'r').readlines())
#这种方法简单,但是可能比较慢,当文件比较大时甚至不能工作。

#可以利用enumerate():
count = 0
for index, line in enumerate(open(filepath,'r')): 
    count += 1
  •  hash函数

描述

hash() 用于获取取一个对象(字符串或者数值等)的哈希值。

语法

hash 语法:

hash(object)

参数说明:

  • object -- 对象;

返回值

返回对象的哈希值。

实例

>>>hash('test')            # 字符串
2314058222102390712
>>> hash(1)                 # 数字
1
>>> hash(str([1,2,3]))      # 集合
1335416675971793195
>>> hash(str(sorted({'1':1}))) # 字典
7666464346782421378
>>>

hash() 函数的用途

hash() 函数的对象字符不管有多长,返回的 hash 值都是固定长度的,也用于校验程序在传输过程中是否被第三方(木马)修改,如果程序(字符)在传输过程中被修改hash值即发生变化,如果没有被修改,则 hash 值和原始的 hash 值吻合,只要验证 hash 值是否匹配即可验证程序是否带木马(病毒)。

name1='正常程序代码'
name2='正常程序代码带病毒'
print(hash(name1)) # 2403189487915500087
print(hash(name2)) # -8751655075885266653

 

hash()函数

在python中有内置的哈希函数hash(),返回一个对象(数字、字符串,不能直接用于 list、set、dictionary)的哈希值。示例代码如下:

# coding:utf-8
# hash()

print(hash(1))
print(hash(1.0))    # 相同的数值,不同类型,哈希值是一样的
print(hash("abc"))
print(hash("hello world"))

在运行时发现了一个现象:相同字符串在同一次运行时的哈希值是相同的,但是不同次运行的哈希值不同。这是由于Python的字符串hash算法有一个启动时随机生成secret prefix/suffix的机制,存在随机化现象:对同一个字符串输入,不同解释器进程得到的hash结果可能不同。
因此当需要做可重现可跨进程保持一致性的hash,需要用到hashlib模块。
3.3 hashlib模块 hashlib提供了常见的摘要算法,如MD5,SHA1等等。示例代码如下: # coding:utf-8 # 使用hashlib模块 import hashlib md5 = hashlib.md5() # 应用MD5算法 data = "hello world" md5.update(data.encode('utf-8')) print(md5.hexdigest())
  •  zip函数

描述

zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。

如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。

zip 方法在 Python 2 和 Python 3 中的不同:在 Python 3.x 中为了减少内存,zip() 返回的是一个对象。如需展示列表,需手动 list() 转换。

如果需要了解 Pyhton3 的应用,可以参考 Python3 zip()

语法

zip 语法:

zip([iterable, ...])

参数说明:

  • iterabl -- 一个或多个迭代器;

返回值

返回元组列表。

 

print(list(zip(('a','b','c'),(1,2,3))))
print(list(zip(('a','b','c'),(1,2,3,4))))
print(list(zip(('a','b','c','d'),(1,2,3))))

p={'name:':'alex','age':'48','gender':'none'}
print(list(zip(p.keys(),p.values())))

输出结果:
[('a', 1), ('b', 2), ('c', 3)]
[('a', 1), ('b', 2), ('c', 3)]
[('a', 1), ('b', 2), ('c', 3)]
[('name:', 'alex'), ('age', '48'), ('gender', 'none')]

 

 

>>>a = [1,2,3]
>>> b = [4,5,6]
>>> c = [4,5,6,7,8]
>>> zipped = zip(a,b)     # 打包为元组的列表
[(1, 4), (2, 5), (3, 6)]
>>> zip(a,c)              # 元素个数与最短的列表一致
[(1, 4), (2, 5), (3, 6)]
>>> zip(*zipped)          # 与 zip 相反,*zipped 可理解为解压,返回二维矩阵式
[(1, 2, 3), (4, 5, 6)]
  •  max函数
dic={'age1':10,'age2':80,'age3':30}
print(max(dic))  #比较的是key
print(max(dic.values())) #比较的是values,但不知道是哪个key对应的?
print(max(zip(dic.values(),dic.keys()))) #结合zip,就可以取出最大的values和对应的key

输出结果:
age3
80
(80, 'age2')

 

#取出最大的值
people=[
    {'name':'alex','age':1000},
    {'name':'wupei','age':10000},
    {'name':'yuanhao','age':9000},
    {'name':'linhaifeng','age':18},
]
print(max(people,key=lambda  dic:dic['age']))

输出结果:
{'name': 'wupei', 'age': 10000}
  •  ord函数

描述

ord() 函数是 chr() 函数(对于8位的ASCII字符串)或 unichr() 函数(对于Unicode对象)的配对函数,它以一个字符(长度为1的字符串)作为参数,返回对应的 ASCII 数值,或者 Unicode 数值,如果所给的 Unicode 字符超出了你的 Python 定义范围,则会引发一个 TypeError 的异常。

语法

以下是 ord() 方法的语法:

ord(c)

参数

  • c -- 字符。

返回值

返回值是对应的十进制整数。

>>>ord('a')
97
>>> ord('b')
98
>>> ord('c')
99
  •  slice函数

描述

slice() 函数实现切片对象,主要用在切片操作函数里的参数传递。

语法

slice 语法:

class slice(stop)
class slice(start, stop[, step])

参数说明:

  • start -- 起始位置
  • stop -- 结束位置
  • step -- 间距

返回值

返回一个切片对象。

切片(Slice)的用法:
例:L[1,2,3]
       L[0:3]:从索引0开始取,直到索引3为止,不包括索引3,即索引0,1,2
       L[1:3]:从索引1开始,取出2个元素出来
       L[:]:表示从头到尾
       L[-2:-1]:表示从倒数第二个元素取到最后一个元素,即输出倒数第二个元素
       L[-3:]:表示从头取到尾
       L[-1:-3:-1]:表示从倒数第一个数按-1取,取至-3为止,即输出最后两个元素
注:最后一个元素为-1。
       切片操作对于tuple也同样适用。
—利用切片(Slice)操作指定参数:
L[parameter 1:parameter 2:parameter 3]:parameter 3表示每N个取一个
例如:L = range(0, 101)
           L[3::3],代表每3个数里取一个,取的数是这3个数中的第一个数
这行代码的意思是,从L[3]开始取,每三个取一个,L[3]==3,所以取的是3的倍数
L = range(0, 101)
print (L[0:9])        #取前10个数
print (L[3::3])         #取3的倍数
print (L[5:51:5])     # 取不大于50的5的倍数

 

列表元素支持用索引访问,正向索引从0开始
   colors=["red","blue","green"]
   colors[0] =="red"
   colors[1]=="blue"
 同时,也可以使用负向索引(python中有序序列都支持负向索引)
   colors[-1]=="green"
列表的切片操作
  切片操作不是列表特有的,python中的有序序列都支持切片,如字符串,元组。
  切片的返回结果类型和切片对象类型一致,返回的是切片对象的子序列,
如:对一个列表切片返回一个列表,

  字符串切片返回字符串。

  切片生成的子序列元素是源版的拷贝。因此切片是一种浅拷贝。

  li=["A","B","C","D"]

  格式:  li[start : end : step]    

 start是切片起点索引,end是切片终点索引,但切片结果不包括终点索引的值。step是步长默认是1。

      t=li[0:3]        ["A","B","C"]        #起点的0索引可以省略,t=li[:3]

       t=li[2: ]        ["C","D"]           #省略end,则切到末尾

      t=li[1:3]        ["B","C"]

      t=li[0:4:2]       ["A","C"]       #从li[0]到li[3],设定步长为2。

 如何确定start和end,他们是什么关系?
       在step的符号一定的情况下,start和end可以混合使用正向和反向索引,无论怎样,你都要保证
      start和end之间有和step方向一致元素 间隔,否则会切出空列表

           t=li[0:2]

            t=li[0:-2]

            t=li[-4:-2]

            t=li[-4:2]

            上面的结果都是一样的;t为["A","B"]

         t=li[-1:-3:-1]

         t=li[-1:1:-1]

         t=li[3:1:-1]

         t=li[3:-3:-1]


         上面的结果都是一样的;t为["D","C"]

         t=li[-1:-3]

         t=li[-1:1]

         t=li[3:1]

         t=li[3:-3]

         都切出空列表

    
      同时,step的正负决定了切片结果的元素采集的先后

               
     省略start  和 end表示以原列表全部为目标


      t=li[::-1]     t--->["C","B","A"]     #反向切,切出全部

        
      t=li[:]        t--->["A","B","C","D"]   #正向切全部
  •  sort函数 

描述

sort() 函数用于对原列表进行排序,如果指定参数,则使用比较函数指定的比较函数。

语法

sort()方法语法:

list.sort(cmp=None, key=None, reverse=False)

参数

  • cmp -- 可选参数, 如果指定了该参数会使用该参数的方法进行排序。
  • key -- 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。
  • reverse -- 排序规则,reverse = True 降序, reverse = False 升序(默认)。

返回值

该方法没有返回值,但是会对列表的对象进行排序。

 

以下实例展示了 sort() 函数的使用方法:
实例
#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
aList = [123, 'Google', 'Runoob', 'Taobao', 'Facebook'];
 
aList.sort();
print "List : ", aList

以上实例输出结果如下:

List :  [123, 'Facebook', 'Google', 'Runoob', 'Taobao']

以下实例降序输出列表:
实例
#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
# 列表
vowels = ['e', 'a', 'u', 'o', 'i']
 
# 降序
vowels.sort(reverse=True)
 
# 输出结果
print '降序输出:', vowels

以上实例输出结果如下:

降序输出: ['u', 'o', 'i', 'e', 'a']

以下实例演示了通过指定列表中的元素排序来输出列表:
实例
#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
# 获取列表的第二个元素
def takeSecond(elem):
    return elem[1]
 
# 列表
random = [(2, 2), (3, 4), (4, 1), (1, 3)]
 
# 指定第二个元素排序
random.sort(key=takeSecond)
 
# 输出类别
print '排序列表:', random

以上实例输出结果如下:

排序列表:[(4, 1), (2, 2), (1, 3), (3, 4)]

 

people=[
    {'name':'alex','age':1000},
    {'name':'wupei','age':10000},
    {'name':'yuanhao','age':9000},
    {'name':'linhaifeng','age':18},
]
print(sorted(people,key=lambda dic:dic['age']))
print(sorted(people,key=lambda dic:dic['age'],reverse=True))
输出结果: [{'name': 'linhaifeng', 'age': 18}, {'name': 'alex', 'age': 1000}, {'name': 'yuanhao', 'age': 9000}, {'name': 'wupei', 'age': 10000}]
[{'name': 'wupei', 'age': 10000}, {'name': 'yuanhao', 'age': 9000}, {'name': 'alex', 'age': 1000}, {'name': 'linhaifeng', 'age': 18}]

 

posted on 2019-01-21 16:53  denny_djl  阅读(256)  评论(0)    收藏  举报

导航