猴子分桃python递归方法_Python编程练习

本文通过实例讲解了Python编程中的递归方法、类与函数的使用,以及列表解析的常见应用。文章涵盖函数默认参数陷阱、类的继承、闭包、多重lambda表达式、数据结构操作、文件路径处理、斐波那契数列、装饰器等多个主题,旨在提升读者的Python编程技能。
摘要由CSDN通过智能技术生成

函数默认参数为可变类型([ ])

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

# 下面代码的输出结果是什么,请解释。

def extend_list(val, list=[]):

list.append(val)

return list

list1 = extend_list(10)

list2 = extend_list(123, [])

list3 = extend_list('a')

print(list1)

print(list2)

print(list3)

print(list1 is list3)

依次输出:

[10, ‘a’]

[123]

[10, ‘a’]

True

因为list1和list3调用函数extend_list时,没有传入list关键字参数,使用了函数初始化的list。

返回给list1和list3的都是初始化list的地址,所以值相同。

类的继承

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

# 下面代码的输出结果是什么,请解释。

class Parent(object):

x = 1

class Child1(Parent):

pass

class Child2(Parent):

pass

print(Parent.x, Child1.x, Child2.x)

Child1.x = 2

print(Parent.x, Child1.x, Child2.x)

Parent.x = 3

print(Parent.x, Child1.x, Child2.x)

依次输出:

1 1 1

1 2 1

3 2 3

因为,Child1、Child2都继承Parent类。

第一次都输出Parent的x值,为1。

第二次,Child1拥有自己的属性x=2,他的输出变为2。

第三次,Parent的属性x被赋值为3。不改变Child1自己的属性x。

列表中多个lambda

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

# 以下代码的输出结果是什么?请写出答案并解释。请修改multipliers的定义,来产生期望的结果。

def multipliers():

return [lambda x: i * x for i in range(4)]

print([m(2) for m in multipliers()])

# [6, 6, 6, 6]

# i在闭包作用域,Python的闭包是迟绑定,闭包用到变量的值,在内部函数被调用时才能得到。

# 把闭包作用域改为局部作用域

def multipliers1():

return [lambda x, i=i: i * x for i in range(4)]

# 变成生成器,使用时赋值

def multipliers2():

return (lambda x: i * x for i in range(4))

print([m(2) for m in multipliers1()])

print([m(2) for m in multipliers2()])

# [0, 2, 4, 6]

打印文件夹中文件的路径以及包含文件夹中文件的路径

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

# 方法一:(面试要求不使用os.walk)

def print_directory_contents(sPath):

import os

for sChild in os.listdir(sPath):

sChildPath = os.path.join(sPath, sChild)

if os.path.isdir(sChildPath):

print_directory_contents(sChildPath)

else:

print(sChildPath)

# 方法二:(使用os.walk)

def print_directory_contents(sPath):

import os

for root, _, filenames in os.walk(sPath):

for filename in filenames:

print(os.path.abspath(os.path.join(root, filename)))

print_directory_contents('.')

列表解析

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

A0 = dict(zip(('a', 'b', 'c', 'd', 'e'), (1, 2, 3, 4, 5)))

A1 = range(10)

A2 = [i for i in A1 if i in A0]

A3 = [A0[s] for s in A0]

A4 = [i for i in A1 if i in A3]

A5 = {i: i * i for i in A1}

A6 = [[i, i * i] for i in A1]

'''

A0:{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}

A1:range(0, 10)

A2:[]

A3:[1, 2, 3, 4, 5]

A4:[1, 2, 3, 4, 5]

A5:{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}

A6:[[0, 0], [1, 1], [2, 4], [3, 9], [4, 16], [5, 25], [6, 36], [7, 49], [8, 64], [9, 81]]

'''

一句话打印出0-100内的偶数

1

2

3

print([i for i in range(1, 101) if i % 2 == 0])

print([i for i in range(2, 101, 2)])

print(list(filter(lambda x: True if x % 2 == 0 else False, range(1, 101))))

1,2,3,4,5 能组成几个互不相同且无重复数字的三位数

1

2

3

nums = [1, 2, 3, 4, 5]

l1 = [i * 100 + j * 10 + k for i in nums for j in nums for k in nums if (j != i and k != j and k != i)]

print(l1, len(l1))

两个字典相加,不同的key对应的值保留,相同的key对应的值相加

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

dicta = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'f': 'hello'}

dictb = {'a': 2, 'b': 3, 'd': 5, 'e': 7, 'm': 9, 'f': 'world'}

def merge(dic1, dic2):

d = {}

for i in dic1:

if i in dic2:

d.setdefault(i, (dic1[i] + dic2[i]))

else:

d.setdefault(i, dic1[i])

for i in dictb:

if i not in d:

d.setdefault(i, dic2[i])

return d

print(merge(dicta, dictb))

def merge(dic1, dic2):

d1keys = list(dic1.keys())

d2keys = list(dic2.keys())

keys = sorted(list(set(d1keys + d2keys)))

ret = {}

for i in keys:

if i in d1keys and i in d2keys:

ret[i] = dic1[i] + dic2[i]

elif i in d1keys and i not in d2keys:

ret[i] = dic1[i]

else:

ret[i] = dic2[i]

return ret

print(merge(dicta, dictb))

斐波那契数列

返回Fibonacci数列中的第n项

1

2

3

4

5

6

7

8

9

10

11

12

13

14

# 方法一 递归法:

def fibo1(n):

if n <= 1:

return n

return fibo1(n - 1) + fibo1(n - 2)

# 方法二 序列解包:

def fibo2(n):

'''序列解包'''

a, b = 0, 1

for i in range(0, n ):

# print(a, b, a + b)

a, b = b, a + b

return a

返回Fibonacci数列中的前n项

1

2

3

4

5

6

7

def fibo3(n):

ret = [0,]

a, b = 0, 1

for i in range(0, n):

a, b = b, a + b

ret.append(a)

return ret

求400万以内最大的斐波那契数和它的下标

1

2

3

4

5

6

7

8

9

10

11

12

def fibo(n):

i, a, b = 1, 1, 2

ret = [a, ]

while b <= n:

a, b = b, a + b

i += 1

ret.append(a)

return a, i, ret

print(fibo(4000000))

求两个列表list的交集和差集

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

l1 = [1, 2, 3, 4]

l2 = [2, 3, ]

# 交集

ret = [i for i in l2 if i in l1]

print(ret)

print(list(set(l1) & set(l2)))

# 差集

ret = [i for i in l1 if i not in l2]

print(ret)

print(list(set(l1) ^ set(l2)))

# 并集

ret = [list(set(l1) | set(l2))]

print(ret)

列表去重(保持原有顺序)

1

2

3

4

5

6

7

8

9

10

11

l1 = [1, 4, 3, 3, 4, 2, 3, 4, 5, 6, 1]

new_l1 = list(set(l1))

new_l1.sort(key=l1.index)

print(new_l1)

from functools import reduce

l1 = [1, 4, 3, 3, 4, 2, 3, 4, 5, 6, 1]

func = lambda x, y: x if y in x else x + [y]

new_l1 = reduce(func, [[], ] + l1)

print(new_l1)

求数组中没有重复的数的和

1

2

3

4

5

6

7

8

def sums(l):

s = set(l)

ret = [i for i in s if l.count(i) == 1]

print(ret)

return sum(ret)

print(sums([3, 4, 1, 2, 5, 6, 6, 5, 4, 3, 3]))

给定一个整数数组返回两个数的索引,使得他们相加和一个目标值相等

1

2

3

4

5

6

7

8

9

10

11

def func(list, target):

for i in range(len(list)):

num = target - list[i]

if num in list and i != list.index(num):

return [i, list.index(num)]

return None

if __name__ == '__main__':

nums = [2, 7, 11, 15]

print(func(nums, 22))

求列表中第二大的元素

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

def max2_func(li):

max = li[0]

max2 = li[1]

if max < max2:

max, max2 = max2, max

for i in range(2, len(li)):

if max < li[i]:

max2, max = max, li[i]

elif max2 < li[i]:

max2 = li[i]

return max2

print(max2_func([1, 2, 3, 4, 5]))

print(max2_func([5, 5, 4, 4, 3]))

0-99取10个不重复的数字

1

2

3

4

5

6

7

8

9

10

11

12

def func(k):

import random

ret = set()

while len(ret) < k:

s = k - len(ret)

l = list(set(range(100)) - ret)

ret = ret | set(random.choices(l, k=s))

return ret

print(func(10))

99乘法表

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

# 方法一

for i in range(1, 10):

for j in range(1, i + 1):

print("%s*%s=%s" % (i, j, i * j), end=' ')

print()

# 方法二

print(["%s*%s=%s" % (i, j, i * j) for i in range(1, 10) for j in range(1, i + 1)])

# 方法三

i, j = 1, 1

while j <= 9:

if i <= j:

print("%s*%s=%s" % (i, j, i * j), end=' ')

i += 1

else:

i = 1

j += 1

print()

写一个装饰器,打印出方法执行时长的信息

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

import time

from functools import wraps

def tiemer(func):

@wraps(func)

def wrapper(*args, **kwargs):

start_time = time.time()

func(*args, **kwargs)

print('%s 运行了%s' % (func.__name__, time.time() - start_time))

return wrapper

@tiemer

def f1():

time.sleep(1)

f1()

写一个装饰器,打印函数名

1

2

3

4

5

6

7

8

9

10

11

12

13

14

def log(func):

def wrapper(*args, **kwargs):

print("call {name}({arg})".format(name=func.__name__, arg=str(*args) or ''))

func(*args, **kwargs)

return wrapper

@log

def now(*args, **kwargs):

print('2013-12-25')

now()

输入一个字符串,返回倒序排列的结果:如:’abcdef’ 返回 ‘fedcba’

1

2

3

4

5

s = 'abcdef'

print(s[::-1])

s1 = ''.join(sorted(s, reverse=True))

print(s1)

返回字段和对应值组成的字典

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

# -*- coding: utf-8 -*-

# __author__ = "maple"

# 有一个数据结构如下,编写函数从该结构数据中返回由指定的字段和对应的值组成的字典。如果指定字段不存在,则跳过该字段。

"""

data = {'time': '2016-08-05T13;13:05',

'some_id': 'ID1234',

'grp1': {'fld1': 1, 'fld2': 2},

'xxx2': {'fld3': 0, 'fld5': 0.4},

'fld6': 11,

'fld7': 7,

'fld46': 8

}

fields:由"|"连接的以"fld"开头的字符串,如:'fld2|fld3|fld7|fld19'

"""

def select(data, fields):

field_list = fields.split('|')

temp = {}

for key, values in data.items():

if isinstance(values, dict):

temp.update(values)

else:

temp[key] = values

result = {i: temp[i] for i in temp if i in field_list}

# for key in temp:

# if key in field_list:

# result[key] = temp[key]

return result

if __name__ == '__main__':

data1 = {'time': '2016-08-05T13;13:05',

'some_id': 'ID1234',

'grp1': {'fld1': 1, 'fld2': 2},

'xxx2': {'fld3': 0, 'fld5': 0.4},

'fld6': 11,

'fld7': 7,

'fld46': 8

}

fields1 = 'fld2|fld3|fld7|fld19'

print(select(data1, fields1))

五猴分桃问题

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

def show(n):

for i in range(1, 6):

t = (n - 1) / 5

print('%s 总数为%s个,第%s只猴子拿走%s个' % (i, n, i, t))

n = 4 * t

def peach():

pea = 1 # 假设最后一只猴子拿走了1个桃子

while True:

num = pea

for i in range(4):

num = 5 * num + 1 # 拿之前的总量

if num % 4: #

break

num /= 4 # 前一个猴子拿走的桃子个数

else:

show(5 * num + 1)

break

pea += 1

return pea, 5 * num + 1

if __name__ == '__main__':

pea, num = peach()

print(pea, num)

罗马数字转阿拉伯数字

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

def rome_to_arab(s):

'''

5、10的左边只能有一个1

50、100左边只能有一个10

500、1000左边只能有一个100

5、50、500 不能放在大数的左边,放在大数的右边只能有一个

1、10、100 可连用最多3个,左边只能有一个

'''

rome_int = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}

num = rome_int[s[0]]

for i in range(1, len(s)):

if rome_int[s[i]] > rome_int[s[i - 1]]:

num += rome_int[s[i]] - 2 * rome_int[s[i - 1]]

else:

num += rome_int[s[i]]

return num

print(rome_to_arab('XXXIX'))

level(x)根据输入数值返回对应级别

1

2

3

4

5

6

7

8

9

10

def level(x):

if x <= 0:

return '数字超出范围'

if x > 200:

return 21

else:

return x // 10 if x % 10 == 0 else x // 10 + 1

print(level(1))

输入年月日,返回天数

1

2

3

4

5

6

7

8

9

10

11

12

13

import datetime

import time

def func(date_str): # 直接使用Python内置模块datetime的格式转换功能得到结果

date_int = list(map(lambda x: int(x), date_str.split('-')))

date = datetime.date(*date_int)

return date.strftime('%j')

# return time.strptime(date_str, "%Y-%m-%d").tm_yday

print(func('2017-12-10'))

根据数字长度创建字典

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

L = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 32768, 65536, 4294967296]

L_str_list = [str(i) for i in L]

ret = {}

for i in L_str_list:

if len(i) not in ret:

ret[len(i)] = [int(i)]

else:

ret[len(i)].append(int(i))

# ret = set(map(lambda x: len(x), L_str_list))

# ret = {i: [] for i in ret}

# for i in L_str_list:

# ret[len(i)].append(int(i))

#

print(ret)

根据(row,column),创建二维数组

1

2

3

4

5

6

7

8

9

10

11

12

13

def array(row, col):

ret = []

for i in range(row):

ret.append([(i * j) for j in range(col)])

return ret

print(array(4, 5))

row = 4

col = 5

print([[(i * j) for j in range(col)] for i in range(row)])

二维数组的成员判断

在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。

请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数,如果存在返回该整数的位置。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

arr = [[1, 4, 7, 10, 15],

[2, 5, 8, 12, 19],

[3, 6, 9, 16, 22],

[10, 13, 14, 17, 24],

[18, 21, 23, 26, 30]]

def get_num(num, data=None):

temp = data.copy()

i, j = 0, len(temp[0]) - 1

while temp:

if num > temp[0][-1]:

del temp[0]

i += 1

elif num < temp[0][-1]:

temp = list(zip(*temp))

del temp[-1]

temp = list(zip(*temp))

j -= 1

else:

return i, j

return False

if __name__ == '__main__':

print(get_num(18, arr))

数组中找最大和的连续子数组

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

def max_son(l):

left = 0

right = len(l) - 1

# mini = l.index(min(l))

# maxi = l.index(max(l))

while left < right:

temp = l[left:right + 1]

mini = l.index(min(temp))

maxi = l.index(max(temp))

print('left %s right %s mini %s maxi %s' % (left, right, mini, maxi))

# 数组两端为正数,整个数组和小于最大值,中间数的和小于0,数组元素最少为4个元素

if sum(l[left:right + 1]) <= l[maxi] and sum(l[left + 1:right]) < 0 and right - left > 2:

if l[left] < l[right] and sum(l[left:right - 1]) < l[maxi]:

left += 1

continue

elif l[left] > l[right] and sum(l[left + 2:right + 1]) < l[maxi]:

right -= 1

continue

if l[left] < 0: # 保证起始数为正数

left += 1

continue

if l[right] < 0: # 保证截止数为正数

right -= 1

continue

if l[left + 1] < 0 and l[left] <= abs(l[left + 1]): # 保证正数后一位的负数小于他本身

left += 2

continue

if l[right - 1] < 0 and l[right] <= abs(l[right - 1]): # 保证正数前一位的负数小于他本身

right -= 2

continue

if left < mini < right and sum(l[mini:right + 1]) <= 0:

right = mini

continue

if left < mini < right and sum(l[left:mini + 1]) <= 0:

left = mini

continue

return left, right, l[left:right + 1]

return left, right, [l[maxi]]

if __name__ == '__main__':

# a = [-2, 1, -3, 4, -7, 2, -1, -3, 4]

# a = [-2, 1, -3, 4, -1, 2, -7, -3, 4]

# a = [-2, 1, -3, 5, -7, 2, -1, -3, 4]

# a = [-2, 1, -3, 5, -7, 4, 3, -3, 4]

# a = [-2, 1, -3, 4, -1, 2, 1, -5, 4]

a = [-2, 1, -3, 4, -1, 2, 1, -4, 5]

# a = [8, -9, 2, 7]

print(max_son(a))

坦克

某次战役中,为便于信息交互,我军侦察部门将此次战役的关键高地坐标设定为(x=0,y=0)并规定,每向东增加100米,x加1,每向北增加100米,y加1。同时,我军情报部门也破译了敌军向坦克发送的指挥信号,其中有三种信号(L,R,M)用于控制坦克的运动,L 和 R 分别表示使令坦克向左、向右转向,M 表示令坦克直线开进100米,其它信号如T用于时间同步,P用于位置较准。

一日,我军侦察兵发现了敌军的一辆坦克,侦察兵立即将坦克所在坐标(P, Q)及坦克前进方向(W:西,E:东,N:北,S:南)发送给指挥部,同时启动信号接收器,将坦克接收到的信号实时同步发往指挥部,指挥部根据这些信息得以实时掌控了该坦克的位置,并使用榴弹炮精准地击毁了该坦克。

请设计合理的数据结构和算法,根据坦克接收到的信号,推断出坦克所在的位置。

设计时请考虑可能的扩展情况,并体现出您的设计风格。

假设,侦察兵发送给指挥部的信息如下:

坦克坐标:(11,39)

坦克运行方向:W

坦克接收到的信号为:MTMPRPMTMLMRPRMTPLMMTLMRRMP

其位置应该是(9,43),运动方向为E

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

class Tank:

pointer = 'NESW' # 方向指针

shift = {'N': 'y+1', 'S': 'y-1', 'W': 'x-1', 'E': 'x+1'} # 位移偏量

def __init__(self, position, direction):

self.x, self.y = position

self.direction = direction

self.position = (self.x, self.y)

def signal(self, orders):

for i in orders:

if i in 'LR':

self.turn(i)

elif i == 'M':

self.move()

elif i == 'P':

self.pd()

def turn(self, orders):

i = self.pointer.find(self.direction)

if orders == 'L':

i -= 1

elif orders == 'R':

i += 1

self.direction = self.pointer[i % 4]

def move(self):

orders = self.shift[self.direction]

if orders[0] == 'x':

x = self.x

self.x = eval(orders)

else:

y = self.y

self.y = eval(orders)

self.position = (self.x, self.y)

def pd(self):

print(self.position, self.direction)

tank = Tank((11, 39), 'W')

tank.signal('MTMPRPMTMLMRPRMTPLMMTLMRRMP')

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值