您的位置:首页 > 编程语言 > Python开发

王亟亟的Python学习之路(六)-递归,迭代,列表生成式

2015-11-19 16:45 826 查看

转载请注明出处:王亟亟的大牛之路

最近事情比较多,也没什么时间学习。(借口,明明在偷懒)

难得空下来,就继续把文章写下去。(玩手游时间更多)

在贴今天要写的内容之前还是先说一下某些概念!(概念还是很重要的,虽然更重要的是理解)

什么是递归?(维基来的)



白话的理解就是某函数自己调用自己

大牛的分析:

递归的基本思想是把规模大的问题转化为规模小的相似的子问题来解决。在函数实现时,因为解决大问题的方法和解决小问题的方法往往是同一个方法,所以就产生了函数调用它自身的情况。另外这个解决问题的函数必须有明显的结束条件,这样就不会产生无限递归的情况了。

什么是迭代?

迭代是函数内某段代码实现循环

迭代和普通循环的区别?

循环代码中参与运算的变量同时是保存结果的变量,当前保存的结果作为下一次循环计算的初始值。

递归循环中,遇到满足终止条件的情况时逐层返回来结束。

平时场景可能是这样子的:



表生成式是Python中对上述两种模式的封装,之后会详细给大家说明

今天的大部分例子将会用Java和Python来实现两种相同效果下的不同代码,让他加会觉得高级语言是有多么方便编写(不是黑Java 毕竟是老牌语言啊 哈哈)

递归的概念在上面已经简单的描述了,这下就简单的写个例子:

如何实现1*2*3*4*5?

最2B的写法:

def aa(a,b,c,d,e):
return a*b*c*d*e
print(aa(1,2,3,4,5))


结果:120

那如果是20个,30个参数呢?难道我再传入20个,30个参数吗?

我们可以从业务逻辑中找前后数字的逻辑关系

x,x+1,x+1+1…依次递增

那我们就可以写一个方法如下:

def aa(flag):
if flag==1:
return 1
return flag*aa(flag-1)

结果也是上面的120


java中:

public static void main(String[] asa) {
System.out.println(mRecursive(5,1));
}

public static int mRecursive(int flag,int value) {
if (flag == 1)
return value;
return mRecursive(flag-1,value*flag);
}

结果也是120


但是过度的调用会使得栈溢出,所以引入尾递归,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。而是返回一个已经存在的值,这样就避免了栈溢出,因为永远只有一个栈

代码如下:

#尾递归方式
def fact_iter(num, k):
if num == 1:
return k
return fact_iter(num - 1, num * k)

def fact(n):
return fact_iter(n, 1)

调用fact(5)结果也是 120


是不是很方便?当然刚开始的时候会对这一类的概念会很混乱(跪拜算法大牛啊)

那要么尝试算下Fibonacci数列的前X位?

答案会在git中呈现

最常用的迭代就是用for,while之类的循环去遍历一个数组/元组等内的元素,如:

nList=[]
flagK=4
for i in range(flagK):
nList.append(listA[i])
print("第38行打印",nList)

结果:第38行打印 [1, 3, 5, 7]


在Java中:

public static void main(String[] asa) {
ArrayList<Integer> list = new ArrayList<Integer>();
for (int k = 0; k < 10; k++) {
list.add(k);
}

System.out.println(list);
}

结果:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]


还可以迭代字符串,dic等

d={"a":1,"b":2,"1b":3}
for value1 in d:
print(value1,end=" ")
print("第66行,迭代一个字典的key,但是是无序的哦")

结果   a 1b b 第66行,迭代一个字典的key,但是是无序的哦

for value2 in d.items():
print(value2,end=" ")
print("第70行,迭代一个字典,但是是无序的哦")

结果   ('a', 1) ('1b', 3) ('b', 2) 第70行,迭代一个字典,但是是无序的哦

//需要导包
from collections import Iterable
print("第74行判断对象是否能被迭代",isinstance('abc', Iterable))

结果   第74行判断对象是否能被迭代 True

print("第75行判断对象是否能被迭代",isinstance(False, Iterable))

结果   第75行判断对象是否能被迭代 False

//迭代list并显示下标
for i, value in enumerate(['A', 'B', 'C']):
print(i, value,end="   ")
print("第78行,显示下标需要调用enumerate函数")

结果   0 A   1 B   2 C   第78行,显示下标需要调用enumerate函数

//多项迭代
for x, y,z in [(1, 1, 3), (3,2, 4), (4,3, 9)]:
print(x, y,z,end="     ")

结果:   1 1 3     3 2 4     4 3 9


而在Python中,提供了更简便的功能“切片”,切片有什么效果?

listA原型: [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99]

print("第41行切片操作",listA[0:3])

结果  第41行切片操作 [1, 3, 5]

print("第42行切片操作,取最后一个",listA[-1])
结果   第42行切片操作,取最后一个 99
//Python支持L[-1]取倒数第一个元素

print("第43行切片操作,取倒数三个,左边元素不包括自己",listA[-4:-1])
结果   第43行切片操作,取倒数三个,左边元素不包括自己 [93, 95, 97]
//诸如 L[0:3]表示,从索引0开始取,直到索引3为止,但不包括索引3。即索引0,1,2,正好是3个元素。

print("第44行,用切片创建10位的list",list(range(10)))
结果   第44行,用切片创建10位的list [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
//可以通过切片轻松取出某一段数列

print("第45行,前10个数,每两个取一个",listA[:10:2])
结果  第45行,前10个数,每两个取一个 [1, 5, 9, 13, 17]

print("第46行每两个取一个",listA[::2])
结果  第46行每两个取一个 [1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61, 65, 69, 73, 77, 81, 85, 89, 93, 97]

print("第47行复制原来的集合",listA[:])
结果 第47行复制原来的集合 [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99]
//只写[:]就可以原样复制一个list


还可以对字符串,元组等进行切片

mTuple=(1,2,3,4,5,6,7,8,9,10)
print('第51行,元组切片',mTuple[2:10])
结果   第51行,元组切片 (3, 4, 5, 6, 7, 8, 9, 10)

print("第52行,元组复制",mTuple[::])

结果   第52行,元组复制 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

#对字符串进行切片
##字符串的切片
print('第55行,切片HelloWorld,返回的也是字符串','helloworld'[2:6])
结果:   第55行,切片HelloWorld,返回的也是字符串 llow


列表生成式

Python内置的非常简单却强大的可以用来创建list的生成式

例子:

如果要列出0-20内%==0的数呢?

Java:

for (int k = 0; k < 20; k++) {
if (k % 3 == 0) {
list1.add(k);
}
}
System.out.println(list1);

结果:   [0, 3, 6, 9, 12, 15, 18]


Python循环:

La=[]
for x in range(20):
if x%3==0:
La.append(x)
print(La)

结果:   [0, 3, 6, 9, 12, 15, 18]


那如果使用列表生成式呢?

print("第86行列表生成表达式",[x for x in range(20) if x%3==0])

结果:   第86行列表生成表达式 [0, 3, 6, 9, 12, 15, 18]
//是不是代码量少了许多,而且可读性也很强

//其他演示

print("第87行,多层循环",[m + n for m in 'ABCD' for n in 'XYZ'])
结果:   第87行,多层循环 ['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ', 'DX', 'DY', 'DZ']

print("第89行循环读出同级目录内容",[d for d in os.listdir('.')])
结果:   第89行循环读出同级目录内容 ['.idea', 'l2demo.py', 'l3demo.py', 'l4demo.py']


这3个功能模块在我们平时的代码编写中的出现几率很高,而Python的大牛们已经给我们写好现成的了,我们只需要使用即可

源码地址:https://github.com/ddwhan0123/PythonExample/blob/master/%E7%A4%BA%E4%BE%8B/l4demo.py

感谢点个赞!

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: