python列表生成式与列表生成器的使用,python生成式

by admin on 2019年9月3日

在Python中使用列表生成式的教程,python生成式

列表生成式即List
Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。

举个例子,要生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]可以用range(1,
11):

>>> range(1, 11)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

但如果要生成[1×1, 2×2, 3×3, …, 10×10]怎么做?方法一是循环:

>>> L = []
>>> for x in range(1, 11):
...  L.append(x * x)
...
>>> L
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

但是循环太繁琐,而列表生成式则可以用一行语句代替循环生成上面的list:

>>> [x * x for x in range(1, 11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

写列表生成式时,把要生成的元素x *
x放到前面,后面跟for循环,就可以把list创建出来,十分有用,多写几次,很快就可以熟悉这种语法。

for循环后面还可以加上if判断,这样我们就可以筛选出仅偶数的平方:

>>> [x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]

还可以使用两层循环,可以生成全排列:

>>> [m + n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']

三层和三层以上的循环就很少用到了。

运用列表生成式,可以写出非常简洁的代码。例如,列出当前目录下的所有文件和目录名,可以通过一行代码实现:

>>> import os # 导入os模块,模块的概念后面讲到
>>> [d for d in os.listdir('.')] # os.listdir可以列出文件和目录
['.emacs.d', '.ssh', '.Trash', 'Adlm', 'Applications', 'Desktop', 'Documents', 'Downloads', 'Library', 'Movies', 'Music', 'Pictures', 'Public', 'VirtualBox VMs', 'Workspace', 'XCode']

for循环其实可以同时使用两个甚至多个变量,比如dict的iteritems()可以同时迭代key和value:

>>> d = {'x': 'A', 'y': 'B', 'z': 'C' }
>>> for k, v in d.iteritems():
...   print k, '=', v
... 
y = B
x = A
z = C

因此,列表生成式也可以使用两个变量来生成list:

>>> d = {'x': 'A', 'y': 'B', 'z': 'C' }
>>> [k + '=' + v for k, v in d.iteritems()]
['y=B', 'x=A', 'z=C']

最后把一个list中所有的字符串变成小写:

>>> L = ['Hello', 'World', 'IBM', 'Apple']
>>> [s.lower() for s in L]
['hello', 'world', 'ibm', 'apple']

小结

运用列表生成式,可以快速生成list,可以通过一个list推导出另一个list,而代码却十分简洁。

思考:如果list中既包含字符串,又包含整数,由于非字符串类型没有lower()方法,所以列表生成式会报错:

>>> L = ['Hello', 'World', 18, 'Apple', None]
>>> [s.lower() for s in L]
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute 'lower'

使用内建的isinstance函数可以判断一个变量是不是字符串:

>>> x = 'abc'
>>> y = 123
>>> isinstance(x, str)
True
>>> isinstance(y, str)
False

请修改列表生成式,通过添加if语句保证列表生成式能正确地执行。

列表生成式即List
Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。…

Python中的列表生成式与生成器学习教程,python生成式

列表生成式 即创建列表的方式,最笨的方法就是写循环逐个生成,前面也介绍过可以使用range()函数来生成,不过只能生成线性列表,下面看看更为高级的生成方式:

>>> [x * x for x in range(1, 11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

写列表生成式时,把要生成的元素x *
x放到前面,后面跟for循环,就可以把list创建出来,十分有用,多写几次,很快就可以熟悉这种语法。
你甚至可以在后面加上if判断:

>>> [x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]

循环嵌套,全排列:

>>> [m + n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']

看一个简单应用,列出当前目录下所有文件和目录:

>>> import os
>>> [d for d in os.listdir('.')]
['README.md', '.git', 'image', 'os', 'lib', 'sublime-imfix', 'src']

前面也说过Python里循环中可以同时引用两个变量,所以生成变量也可以:

>>> d = {'x': 'A', 'y': 'B', 'z': 'C' }
>>> [k + '=' + v for k, v in d.iteritems()]
['y=B', 'x=A', 'z=C']

也可以通过一个list生成另一个list,例如把一个list中所有字符串变为小写:

>>> L = ['Hello', 'World', 'IBM', 'Apple']
>>> [s.lower() for s in L]
['hello', 'world', 'ibm', 'apple']

但是这里有个问题,list中如果有其他非字符串类型,那么lower()会报错,解决办法:

>>> L = ['Hello', 'World', 'IBM', 'Apple', 12, 34]
>>> [s.lower() if isinstance(s,str) else s for s in L]
['hello', 'world', 'ibm', 'apple', 12, 34]

此外,列表生成式还有许多神奇用法,说明请看注释:

#!/usr/bin/env python3 
# -*- coding: utf-8 -*- 

list(range(1, 11)) 

# 生成1乘1,2乘2...10乘10 
L = [] 
for x in range(1, 11): 
  L.append(x * x) 

# 上面太麻烦,看下面 
[x * x for x in range(1, 11)] 
# [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] 

# 加上if,就可以筛选出仅偶数的平方 
[x * x for x in range(1, 11) if x % 2 == 0] 
# [4, 16, 36, 64, 100] 

# 两层循环,可以生成全排列 
[m + n for m in 'ABC' for n in 'XYZ'] 
# ['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ'] 

# 列出当前目录下的所有文件和目录名 
import os 
[d for d in os.listdir('.')] # on.listdir可以列出文件和目录 

# 列表生成式也可以使用两个变量来生成list: 
d = {'x': 'A', 'y': 'B', 'z': 'C'} 
[k + '=' + v for k, v in d.items()] 
# ['x=A', 'z=C', 'y=B'] 

# 把一个list中所有的字符串变成小写 
L = ['Hello', 'World', 'IBM', 'Apple'] 
[s.lower() for s in L] 
# ['hello', 'world', 'ibm', 'apple'] 

L1 = ['Hello', 'World', 18, 'Apple', None] 
L2 = [s.lower() for s in L1 if isinstance(s, str)] 
print(L2) 
# ['hello', 'world', 'apple'] 
# isinstance函数可以判断一个变量是不是字符串 

生成器 列表生成式虽然强大,但是也会有一个问题,当我们想生成一个很大的列表时,会非常耗时,并且占用很大的存储空间,关键是这里面的元素可能你只需要用到前面很少的一部分,大部分的空间和时间都浪费了。Python提供了一种边计算边使用的机制,称为生成器(Generator),创建一个Generator最简单的方法就是把[]改为():

>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x7fe73eb85cd0>

如果要一个一个打印出来,可以通过generator的next()方法:

>>> g.next()
0
>>> g.next()
1
>>> g.next()
4
>>> g.next()
9
>>> g.next()
16
>>> g.next()
25
>>> g.next()
36
>>> g.next()
49
>>> g.next()
64
>>> g.next()
81
>>> g.next()
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
StopIteration

其实generator object也是可迭代的,所以可以用循环打印,还不会报错。

>>> g = (x * x for x in range(10))
>>> for n in g:
...   print n
...

这是简单的推算算法,但是如果算法比较复杂,写在()里就不太合适了,我们可以换一种方式,使用函数来实现。
比如,著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到:
1, 1, 2, 3, 5, 8, 13, 21, 34, …
斐波拉契数列用列表生成式写不出来,但是,用函数把它打印出来却很容易:

def fib(max):
  n, a, b = 0, 0, 1
  while n < max:
    print b
    a, b = b, a + b
    n = n + 1

上面的函数可以输出斐波那契数列的前N个数,这个也是通过前面的数推算出后面的,所以可以把函数变成generator
object,只需要把print b改为yield b即可。

def fib(max):
  n, a, b = 0, 0, 1
  while n < max:
    yield b
    a, b = b, a + b
    n = n + 1

如果一个函数定义中包含了yield关键字,这个函数就不在是普通函数,而是一个generator
object。

>>> fib(6)
<generator object fib at 0x7fa1c3fcdaf0>
>>> fib(6).next()
1

所以要想调用这个函数,需要使用next()函数,并且遇到yield语句返回(可以把yield理解为return):

def odd():
  print 'step 1'
  yield 1
  print 'step 2'
  yield 3
  print 'step 3'
  yield 5

看看调用输出结果:

>>> o = odd()
>>> o.next()
step 1
1
>>> o.next()
step 2
3
>>> o.next()
step 3
5
>>> o.next()
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
StopIteration

同样也可以改为for循环语句输出。例如:

def odd():
  print 'step 1'
  yield 1
  print 'step 2'
  yield 2
  print 'step 3'
  yield 3

if __name__ == '__main__':
  o = odd()
  while True:
    try:
      print o.next()
    except:
      break

python列表生成式与列表生成器的使用,python生成式

列表生成式:会将所有的结果全部计算出来,把结果存放到内存中,如果列表中数据比较多,就会占用过多的内存空间,可能会导致MemoryError内存错误或者导致程序在运行时出现卡顿的情况

列表生成器:会创建一个列表生成器对象,不会一次性的把所有结果都计算出来,如果需要获取数据,可以使用next()函数来获取,但是需要注意,一旦next()函数获取不到数据,会导致出现StopIteration异常错误,可以使用for循环遍历列表生成器,获取所有数据

需要视情况而定,如果数据量比较大,推荐使用生成器

 python2.7中就是range(生成式) 和 xrange(生成器)的区别

列表生成式是快速生成一个列表的一些公式

在列表中存放0~100的数:

普通的列表生成:

numbers=[] 
for x in range(0,101): 
  numbers.append(x) 
print(numbers) 

用列表生成式生成列表:[要放入列表的数据    简单的表达式1   表达式2]

#x for x in range(0,101) for循环遍历出来的值,放入列表中 
numbers=[x for x in range(0,101)] 
print(numbers) 

列表中存放0~100的偶数:

普通方法生成列表:

for x in range(0,101): 
  if x%2==0: 
    numbers.append(x) 
print(numbers) 

用列表生成式生成列表:

#for循环遍历0~101的数字,如果数字对2取余==0,表示是偶数,x放在列表中 
numbers=[x for x in range(0,101)if x%2==0] 
print(numbers) 

找出列表list1=[‘asd’,’adf’,’dafg’,’acbo’]带有a的字符

普通写法:

rs_list=[] 
for s in list1: 
  if 'a' in s: 
    rs_list.append(s) 
print(rs_list) 

列表生成式:

list2=[x for x in list1 if 'a' in x] 

列表生成式支持双层for循环

list3=[x*y for x in range(0,10) for y in range(20)] 
print(list3) 

生成器构造实例

# 使用类似列表生成式的方式构造生成器
g1 = (2*n + 1 for n in range(3, 6))

# 使用包含yield的函数构造生成器
def my_range(start, end):
  for n in range(start, end):
    yield 2*n + 1

g2 = my_range(3, 6)
print(type(g1))
print(type(g2))

输出结果:

<class ‘generator’>
<class ‘generator’>

生成器的调用方式

  1. 要调用生成器产生新的元素,有两种方式:
  2. 调用内置的next()方法
  3. 使用循环对生成器对象进行遍历(推荐)
  4. 调用生成器对象的send()方法

实例1:使用next()方法遍历生成器

print(next(g1))
print(next(g1))
print(next(g1))
print(next(g1))

输出结果:

7
9
11
Traceback (most recent call last):
  File “***/generator.py”, line 26, in <module>
    print(next(g1))
StopIteration

print(next(g2))
print(next(g2))
print(next(g2))
print(next(g2))

输出结果:

7
9
11
Traceback (most recent call last):
  File “***/generator.py”, line 31, in <module>
    print(next(g2))
StopIteration

可见,使用next()方法遍历生成器时,最后是以抛出一个StopIeration异常终止。

实例2:使用循环遍历生成器

for x in g1:
  print(x)

for x in g2:
  print(x)

两个循环的输出结果是一样的:

7
9
11

可见,使用循环遍历生成器时比较简洁,且最后不会抛出一个StopIeration异常。因此使用循环的方式遍历生成器的方式才是被推荐的。

需要说明的是:如果生成器函数有返回值,要获取该返回值的话,只能通过在一个while循环中不断的next(),最后通过捕获StopIteration异常

实例3:调用生成器对象的send()方法

def my_range(start, end):
  for n in range(start, end):
    ret = yield 2*n + 1
    print(ret)

g3 = my_range(3, 6)
print(g3.send(None))
print(g3.send('hello01'))
print(g3.send('hello02'))

输出结果:

7
hello01
9
hello02
11

print(next(g3))
print(next(g3))
print(next(g3))

输出结果:

7
None
9
None
11

结论:

  1. next()会调用yield,但不给它传值
  2. send()会调用yield,也会给它传值(该值将成为当前yield表达式的结果值)

需要注意的是:第一次调用生成器的send()方法时,参数只能为None,否则会抛出异常。当然也可以在调用send()方法之前先调用一次next()方法,目的是让生成器先进入yield表达式。

生成器与列表生成式对比

既然通过列表生成式就可以直接创建一个新的list,那么为什么还要有生成器存在呢?

因为列表生成式是直接创建一个新的list,它会一次性地把所有数据都存放到内存中,这会存在以下几个问题:

  1. 内存容量有限,因此列表容量是有限的;
  2. 当列表中的数据量很大时,会占用大量的内存空间,如果我们仅仅需要访问前面有限个元素时,就会造成内存资源的极大浪费;
  3. 当数据量很大时,列表生成式的返回时间会很慢;

而生成器中的元素是按照指定的算法推算出来的,只有调用时才生成相应的数据。这样就不必一次性地把所有数据都生成,从而节省了大量的内存空间,这使得其生成的元素个数几乎是没有限制的,并且操作的返回时间也是非常快速的(仅仅是创建一个变量而已)。

我们可以做个试验:对比一下生成一个1000万个数字的列表,分别看下用列表生成式和生成器时返回结果的时间和所占内存空间的大小:

import time
import sys

time_start = time.time()
g1 = [x for x in range(10000000)]
time_end = time.time()
print('列表生成式返回结果花费的时间: %s' % (time_end - time_start))
print('列表生成式返回结果占用内存大小:%s' % sys.getsizeof(g1))

def my_range(start, end):
  for x in range(start, end):
    yield x

time_start = time.time()
g2 = my_range(0, 10000000)
time_end = time.time()
print('生成器返回结果花费的时间: %s' % (time_end - time_start))
print('生成器返回结果占用内存大小:%s' % sys.getsizeof(g2))

输出结果:

列表生成式返回结果花费的时间: 0.8215489387512207
列表生成式返回结果占用内存大小:81528056
生成器返回结果花费的时间: 0.0
生成器返回结果占用内存大小:88

可见,生成器返回结果的时间几乎为0,结果所占内存空间的大小相对于列表生成器来说也要小的多。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持帮客之家。

列表生成式:
会将所有的结果全部计算出来,把结果存放到内存中,如果列表中数据比…

浅谈Python中列表生成式和生成器的区别,python生成式

列表生成式语法:

[x*x for x in range(0,10)] //列表生成式,这里是中括号
//结果 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
(x*x for x in range(0,10)) //生成器, 这里是小括号
//结果 <generator object <genexpr> at 0x7f0b072e6140>

二者的区别很明显:
一个直接返回了表达式的结果列表,
而另一个是一个对象,该对象包含了对表达式结果的计算引用,
通过循环可以直接输出

g = (x*x for x in range(0,10))
for n in g:
  print n

结果

0
1
4
9
16
25
36
49
64
81

    当表达式的结果数量较少的时候, 使用列表生成式还好, 一旦数量级过大,
那么列表生成式就会占用很大的内存,
    而生成器并不是立即把结果写入内存, 而是保存的一种计算方式,
通过不断的获取,
可以获取到相应的位置的值,所以占用的内存仅仅是对计算对象的保存

列表生成式语法: [x*x for x in range(0,10)]
//列表生成式,这里是中括号//结果 [0, 1, 4, 9,…

列表生成式:会将所有的结果全部计算出来,把结果存放到内存中,如果列表中数据比较多,就会占用过多的内存空间,可能会导致MemoryError内存错误或者导致程序在运行时出现卡顿的情况

您可能感兴趣的文章:

  • 举例讲解Python中的list列表数据结构用法
  • Python实现列表转换成字典数据结构的方法
  • python生成器表达式和列表解析
  • Python 列表排序方法reverse、sort、sorted详解
  • Python中对元组和列表按条件进行排序的方法示例
  • 初步认识Python中的列表与位运算符
  • 浅谈Python中列表生成式和生成器的区别
  • python列表操作之extend和append的区别实例分析
  • python追加元素到列表的方法
  • Python中map和列表推导效率比较实例分析
  • python通过apply使用元祖和列表调用函数实例
  • 深入解析Python中的list列表及其切片和迭代操作

列表生成式
即创建列表的方式,最笨的方法就是写循环逐个生成,前面也介绍过可以…

列表生成器:会创建一个列表生成器对象,不会一次性的把所有结果都计算出来,如果需要获取数据,可以使用next()函数来获取,但是需要注意,一旦next()函数获取不到数据,会导致出现StopIteration异常错误,可以使用for循环遍历列表生成器,获取所有数据

需要视情况而定,如果数据量比较大,推荐使用生成器

 python2.7中就是range(生成式) 和 xrange(生成器)的区别

列表生成式是快速生成一个列表的一些公式

在列表中存放0~100的数:

普通的列表生成:

numbers=[] 
for x in range(0,101): 
  numbers.append(x) 
print(numbers) 

用列表生成式生成列表:[要放入列表的数据    简单的表达式1   表达式2]

#x for x in range(0,101) for循环遍历出来的值,放入列表中 
numbers=[x for x in range(0,101)] 
print(numbers) 

列表中存放0~100的偶数:

普通方法生成列表:

for x in range(0,101): 
  if x%2==0: 
    numbers.append(x) 
print(numbers) 

用列表生成式生成列表:

#for循环遍历0~101的数字,如果数字对2取余==0,表示是偶数,x放在列表中 
numbers=[x for x in range(0,101)if x%2==0] 
print(numbers) 

找出列表list1=[‘asd’,’adf’,’dafg’,’acbo’]带有a的字符

普通写法:

rs_list=[] 
for s in list1: 
  if 'a' in s: 
    rs_list.append(s) 
print(rs_list) 

列表生成式:

list2=[x for x in list1 if 'a' in x] 

列表生成式支持双层for循环

list3=[x*y for x in range(0,10) for y in range(20)] 
print(list3) 

生成器构造实例

# 使用类似列表生成式的方式构造生成器
g1 = (2*n + 1 for n in range(3, 6))

# 使用包含yield的函数构造生成器
def my_range(start, end):
  for n in range(start, end):
    yield 2*n + 1

g2 = my_range(3, 6)
print(type(g1))
print(type(g2))

输出结果:

<class ‘generator’>
<class ‘generator’>

生成器的调用方式

  1. 要调用生成器产生新的元素,有两种方式:
  2. 调用内置的next()方法
  3. 使用循环对生成器对象进行遍历(推荐)
  4. 调用生成器对象的send()方法

实例1:使用next()方法遍历生成器

print(next(g1))
print(next(g1))
print(next(g1))
print(next(g1))

输出结果:

7
9
11
Traceback (most recent call last):
  File “***/generator.py”, line 26, in <module>
    print(next(g1))
StopIteration

print(next(g2))
print(next(g2))
print(next(g2))
print(next(g2))

输出结果:

7
9
11
Traceback (most recent call last):
  File “***/generator.py”, line 31, in <module>
    print(next(g2))
StopIteration

可见,使用next()方法遍历生成器时,最后是以抛出一个StopIeration异常终止。

实例2:使用循环遍历生成器

for x in g1:
  print(x)

for x in g2:
  print(x)

两个循环的输出结果是一样的:

7
9
11

可见,使用循环遍历生成器时比较简洁,且最后不会抛出一个StopIeration异常。因此使用循环的方式遍历生成器的方式才是被推荐的。

需要说明的是:如果生成器函数有返回值,要获取该返回值的话,只能通过在一个while循环中不断的next(),最后通过捕获StopIteration异常

实例3:调用生成器对象的send()方法

def my_range(start, end):
  for n in range(start, end):
    ret = yield 2*n + 1
    print(ret)

g3 = my_range(3, 6)
print(g3.send(None))
print(g3.send('hello01'))
print(g3.send('hello02'))

输出结果:

7
hello01
9
hello02
11

print(next(g3))
print(next(g3))
print(next(g3))

输出结果:

7
None
9
None
11

结论:

  1. next()会调用yield,但不给它传值
  2. send()会调用yield,也会给它传值(该值将成为当前yield表达式的结果值)

需要注意的是:第一次调用生成器的send()方法时,参数只能为None,否则会抛出异常。当然也可以在调用send()方法之前先调用一次next()方法,目的是让生成器先进入yield表达式。

生成器与列表生成式对比

既然通过列表生成式就可以直接创建一个新的list,那么为什么还要有生成器存在呢?

因为列表生成式是直接创建一个新的list,它会一次性地把所有数据都存放到内存中,这会存在以下几个问题:

  1. 内存容量有限,因此列表容量是有限的;
  2. 当列表中的数据量很大时,会占用大量的内存空间,如果我们仅仅需要访问前面有限个元素时,就会造成内存资源的极大浪费;
  3. 当数据量很大时,列表生成式的返回时间会很慢;

而生成器中的元素是按照指定的算法推算出来的,只有调用时才生成相应的数据。这样就不必一次性地把所有数据都生成,从而节省了大量的内存空间,这使得其生成的元素个数几乎是没有限制的,并且操作的返回时间也是非常快速的(仅仅是创建一个变量而已)。

我们可以做个试验:对比一下生成一个1000万个数字的列表,分别看下用列表生成式和生成器时返回结果的时间和所占内存空间的大小:

import time
import sys

time_start = time.time()
g1 = [x for x in range(10000000)]
time_end = time.time()
print('列表生成式返回结果花费的时间: %s' % (time_end - time_start))
print('列表生成式返回结果占用内存大小:%s' % sys.getsizeof(g1))

def my_range(start, end):
  for x in range(start, end):
    yield x

time_start = time.time()
g2 = my_range(0, 10000000)
time_end = time.time()
print('生成器返回结果花费的时间: %s' % (time_end - time_start))
print('生成器返回结果占用内存大小:%s' % sys.getsizeof(g2))

输出结果:

列表生成式返回结果花费的时间: 0.8215489387512207
列表生成式返回结果占用内存大小:81528056
生成器返回结果花费的时间: 0.0
生成器返回结果占用内存大小:88

可见,生成器返回结果的时间几乎为0,结果所占内存空间的大小相对于列表生成器来说也要小的多。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

您可能感兴趣的文章:

  • Python列表推导式与生成器表达式用法示例
  • 基于Python列表解析(列表推导式)
  • Python列表推导式、字典推导式与集合推导式用法实例分析
  • Python列表推导式的使用方法
  • Python学习小技巧之列表项的推导式与过滤操作
  • Python列表生成式与生成器操作示例
  • Python3中的列表生成式、生成器与迭代器实例详解
  • 举例讲解Python中的迭代器、生成器与列表解析用法
  • 浅谈Python中列表生成式和生成器的区别
  • Python
    while、for、生成器、列表推导等语句的执行效率测试
  • Python列表推导式与生成器用法分析

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图