Python编程练习

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

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')

猜你喜欢

转载自www.cnblogs.com/Hessen/p/8961097.html
今日推荐