一、列表推导式,推导式是可以从一个数据序列

作者: 编程  发布:2019-11-20

推导式 comprehensions(又称解析式):是 Python 中很强大的、很受欢迎的特性,具有语言简洁,速度快等优点。推导式包括:

本文实例讲述了Python列表推导式、字典推导式与集合推导式用法。分享给大家供大家参考,具体如下:

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

推导式comprehensions(又称解析式),是Python的一种独有特性。推导式是可以从一个数据序列构建另一个新的数据序列的结构体。

1. 列表推导式
2. 字典推导式
3. 集合推导式

推导式comprehensions(又称解析式),是Python的一种独有特性。推导式是可以从一个数据序列构建另一个新的数据序列的结构体。 共有三种推导,在Python2和3中都有支持:

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

  • 列表(list)推导式
  • 字典(dict)推导式
  • 集合(set)推导式

对以上的三种推导式分别举例分析:

列表(list)推导式
字典(dict)推导式
集合(set)推导式

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

列表推导式

一、列表推导式


一、列表推导式

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

一、使用[]生成list

基本格式

var = [expression for item in iterable if condition]
expression        # 列表生成元素表达式,可以是有返回值的函数。
for item in iterable    #迭代iterable将item传入expression表达式中。
if condition    #根据条件过滤数据,生成想得到的数据

eg:列表生成式

var =[item for item in range(10) if item % 2 == 0]
print(var)

# 输出
[0, 2, 4, 6, 8]      # 输出为列表

 

二、使用()生成generator

将列表推导式的 [] 换成 () 即可得到  生成器

eg:生成器表达式

gen=('egg%s' %i for i in range(10) if i > 5)
print(gen)
print(list(gen))

# 输出
<generator object <genexpr> at 0x7f4b7c219d58>  # 生成器对象
['egg6', 'egg7', 'egg8', 'egg9']     # 生成器内的数据

 

 

1、使用 [] 生成 list

例如:

list = [ i for i in range(20) if i%2 == 0 ]
print(list)

#output:[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

1、使用[]生成list

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

字典推导式

字典推导和列表推导的使用方法是类似的,只不中括号该改成大括号。直接举例说明

eg:大小写key合并

mcase = {'a': 10, 'b': 34, 'A': 7, 'Z': 3}
mcase_frequency = {
    k.lower(): mcase.get(k.lower(), 0) + mcase.get(k.upper(), 0)
    for k in mcase.keys()
    if k.lower() in ['a','b']
}
print mcase_frequency

# 输出结果
 {'a': 17, 'b': 34}

eg:快速更换key和value

mcase = {'a': 10, 'b': 34}
mcase_frequency = {v: k for k, v in mcase.items()}
print mcase_frequency

# 输出结果
{10: 'a', 34: 'b'}

 

2、使用 () 生成 generator

将列表推导式的 [] 换成 () 即可得到生成器。

generator = ( i for i in range(20) if i%2 == 0 )
print(generator)

#output:<generator object <genexpr> at 0x0000000000B5CA40>

通过 next() 就可以依次调用生成器中的数据。

基本格式

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

集合推导式

跟列表推导式也是类似的。 唯一的区别在于它使用大括号{}。

eg:

squared = {x**2 for x in [1, 1, 2]}
print(squared)
# 输出结果
# set([1, 4])

 

二、字典推导式


存在 key 和 value,使用的是 {}。

dic = { "A":1, "b":2, "C":3, "d":4 }
new_dic = { k:v for k,v in dic.items() if k <= 'a'}
print(new_dic)

#output:{'C': 3, 'A': 1}

variable = [out_exp_res for out_exp in input_list if out_exp == 2]

普通的列表生成:

三、集合推导式


它跟列表推导式也是类似的。区别在于它使用大括号 {},并且数据是无序和无重复的。

Set = { i**2 for i in [1,2,3,4,5,3] }
print(Set)

#output:{16, 1, 4, 9, 25}

out_exp_res:  列表生成元素表达式,可以是有返回值的函数。
for out_exp in input_list:  迭代input_list将out_exp传入out_exp_res表达式中。
if out_exp == 2:  根据条件过滤哪些值可以。

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

例一:

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

multiples = [i for i in range(30) if i % 3 is 0]
print(multiples)
# Output: [0, 3, 6, 9, 12, 15, 18, 21, 24, 27]
#x for x in range(0,101) for循环遍历出来的值,放入列表中 
numbers=[x for x in range(0,101)] 
print(numbers) 

例二:

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

def squared(x):
  return x*x
multiples = [squared(i) for i in range(30) if i % 3 is 0]
print multiples
# Output: [0, 9, 36, 81, 144, 225, 324, 441, 576, 729]

普通方法生成列表:

2、使用()生成generator

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

将俩表推导式的[]改成()即可得到生成器。

用列表生成式生成列表:

multiples = (i for i in range(30) if i % 3 is 0)
print(type(multiples))
# Output: <type 'generator'>
#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的字符

字典推导和列表推导的使用方法是类似的,只不中括号该改成大括号。直接举例说明:

普通写法:

例子一:大小写key合并

rs_list=[] 
for s in list1: 
  if 'a' in s: 
    rs_list.append(s) 
print(rs_list) 
mcase = {'a': 10, 'b': 34, 'A': 7, 'Z': 3}
mcase_frequency = {
  k.lower(): mcase.get(k.lower(), 0) + mcase.get(k.upper(), 0)
  for k in mcase.keys()
  if k.lower() in ['a','b']
}
print mcase_frequency
# Output: {'a': 17, 'b': 34}

9159.com,列表生成式:

例子二:快速更换key和value

list2=[x for x in list1 if 'a' in x] 
mcase = {'a': 10, 'b': 34}
mcase_frequency = {v: k for k, v in mcase.items()}
print mcase_frequency
# Output: {10: 'a', 34: 'b'}

列表生成式支持双层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))
squared = {x**2 for x in [1, 1, 2]}
print(squared)
# Output: set([1, 4])

输出结果:

更多关于Python相关内容感兴趣的读者可查看本站专题:《Python列表(list)操作技巧总结》、《Python数组操作技巧总结》、《Python字符串操作技巧汇总》、《Python函数使用技巧总结》、《Python入门与进阶经典教程》及《Python数据结构与算法教程》

<class 'generator'>
<class 'generator'>

希望本文所述对大家Python程序设计有所帮助。

生成器的调用方式

您可能感兴趣的文章:

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

本文由9159.com发布于编程,转载请注明出处:一、列表推导式,推导式是可以从一个数据序列

关键词: