python 编程题

干货

github上 5280+star 的面试题

python面试题 300 道

django 后端开发面试题

leetcode

自己收集的题

1、如何去除列表中的重复元素

【题目】给出一个列表:lis = [4, 2, 1, 3, 4, 2, 3, 1, 3, 2, 2, 2],去除列表中的重复元素。

lis = [4, 2, 1, 3, 4, 2, 3, 1, 3, 2, 2, 2]
# 解法1: 利用set去重,会改变列表顺序
lis1 = list(set(lis))
# 解法2:
lis2 = []
for i in lis:
if i not in lis2:
lis2.append(i)

2、八大排序算法合集

【题目】给出一个列表: lis = [1, 2, 5, 9, 10, 3, 4, 8, 77, 100]

选择排序

def select_sort(lists):
'''
选择排序(升序)【不稳定排序】
原理:
1、给定一个列表,经过第一轮比较后,找到最小值,与第一个位置交换;
2、接着对不包括第一个元素的剩下的元素,找到最小值,与第二个位置交换;
3、重复该过程,直到进行比较的记录只有一个为止
以 list = [5, 4, 2, 1, 3] 为例:
第一次排序后: [1, 4, 2, 5, 3]
第二次排序后: [1, 2, 4, 5, 3]
第三次排序后: [1, 2, 3, 5, 4]
第四次排序后: [1, 2, 3, 4, 5]
时间复杂度:O(n**2)
空间复杂度:O(1)
:param lists:
:return: lists
'''
count = len(lists)
for i in range(0, count):
min = i
for j in range(i + 1, count):
if lists[min] > lists[j]:
min = j
lists[min], lists[i] = lists[i], lists[min]
return lists
# 调用选择排序
select_sort_list = select_sort(lis)
print(select_sort_list)

插入排序

def insert_sort(lists):
'''
插入排序(升序)【稳定排序】
原理:
1、假设初始时假设第一个记录,自成一个有序序列,其余的记录为无序序列;
2、从第二个记录开始,按记录大小,依次插入之前的有序序列中;
3、直到最后一个记录插入到有序序列中为止
以 list = [5, 4, 2, 1, 3] 为例:
第一步,插入5之后: [5], 4, 2, 1, 3
第二步,插入4之后: [4, 5], 2, 1, 3
第三步,插入2之后: [2, 4, 5], 1, 3
第四步,插入1之后: [1, 2, 4, 5], 3
第五步,插入3之后: [1, 2, 3, 4, 5]
时间复杂度: O(n) ~ O(n**2) 平均: O(n**2)
空间复杂度: O(1)
:param lists:
:return: lists
'''
count = len(lists)
for i in range(1, count):
key = lists[i]
j = i - 1
while j >= 0:
if lists[j] > key:
lists[j+1] = lists[j]
lists[j] = key
j -= 1
return lists
# 调用插入排序
insert_sort_list = insert_sort(lis)
print(insert_sort_list)

冒泡排序

def bubble_sort(lists):
'''
冒泡排序(升序)【稳定排序】
原理:
1、从第一个元素开始,开始依次对相邻的两个元素进行比较,当后面的元素大于前面的元素时,交换二者位置;
2、进行一轮比较之后,最大的元素将在序列尾部(最后一位);
3、然后对(n-1)个元素再进行第二轮比较,最大元素将在序列倒数第二位;
4、重复该过程,直至只剩下最后一个元素为止,最后的元素就是最小值,排在序列首位
以 list = [5, 4, 2, 1, 3] 为例:
第一轮排序: [4, 2, 1, 3, 5]
第二轮排序: [2, 1, 3, 4, 5]
第三轮排序: [1, 2, 3, 4, 5]
时间复杂度: O(n) ~ O(n**2) 平均:O(n**2)
空间复杂度: O(1)
:param lists:
:return lists:
'''
for i in range(len(lists)-1):
for j in range(len(lists)-i-1):
if lists[j] > lists[j+1]:
lists[j], lists[j+1] = lists[j+1], lists[j]
return lists
# 调用冒泡排序
bubble_sort_list = bubble_sort(lis)
print(bubble_sort_list)

归并排序

def merge(left, right):
i, j = 0, 0
result = []
while i < len(left) and j < len(right):
if left[i] <= right[j]:
result.append(left[i])
i += 1
else:
result.append(right[j])
j += 1
result += left[i:]
result += right[j:]
return result
def merge_sort(lists):
'''
归并排序(升序)【稳定排序】
原理:
利用分治法和递归法去解决问题
1、第一步,划分字表;
2、第二步,合并半字表
时间复杂度:O(nlogn)
空间复杂度:O(1)
:param lists:
:return lists:
'''
if len(lists) <= 1:
return lists
num = len(lists) / 2
left = merge_sort(lists[:num])
right = merge_sort(lists[num:])
return merge(left, right)
# 调用归并排序
merge_sort_list = merge_sort(lis)
print(merge_sort_list)

快速排序

def quick_sort(lists, left, right):
'''
快速排序(升序)【不稳定】
原理:
分治递归,给定一组序列,把序列分为两部分,前部分的所有元素比后部分的所有元素小,然后再对前后两部分进行快速排序,递归该过程,直到所有记录
均有序为止。分三步走:
(1)分解,array[m,...,n] 划分成 array1[m,..,k] 和 array2[k+1,...,n], 其中 array1 所有元素 < array2 所有元素
(2)递归求解,递归array1, array2
(3)合并,array[m,...,n] 自动排好序
:param lists:
:param left:
:param right:
:return lists:
'''
if left >= right:
return lists
key = lists[left]
low = left
high = right
while left < right:
while left < right and lists[right] >= key:
right -= 1
lists[left] = lists[right]
while left < right and lists[left] <= key:
left += 1
lists[right] = lists[left]
lists[right] = key
quick_sort(lists, low, left - 1)
quick_sort(lists, left + 1, high)
return lists
# 快速排序调用
quick_sort_list = quick_sort(lis, 0, len(lis) - 1)
print(quick_sort_list)

希尔排序

def shell_sort(lists):
'''
希尔排序(升序)【不稳定排序】
原理:
也叫缩小增量排序,将待排序列分成多个子序列,每个子序列元素个数相对较少,对各个子序列分别进行直接插入排序,待整个排序序列"基本有序后",再对所有元素进行一次直接插入排序
时间复杂度:O(nlogn) 最差 O(n**s)(1<s<2)
空间复杂度:O(1)
:param lists:
:return lists:
'''
count = len(lists)
step = 2
group = int(count / step)
while group > 0:
for i in range(0, group):
j = i + group
while j < count:
k = j - group
key = lists[j]
while k >= 0:
if lists[k] > key:
lists[k + group] = lists[k]
lists[k] = key
k -= group
j += group
group /= step
return lists
# 希尔排序调用
shell_sort_list = shell_sort(lis)
print(shell_sort_list)

堆排序

def adjust_heap(lists, i, size):
lchild = 2 * i + 1
rchild = 2 * i + 2
maxs = i
if i < size / 2:
if lchild < size and lists[lchild] > lists[maxs]:
maxs = lchild
if rchild < size and lists[rchild] > lists[maxs]:
maxs = rchild
if maxs != i:
lists[maxs], lists[i] = lists[i], lists[maxs]
adjust_heap(lists, maxs, size)
def build_heap(lists, size):
for i in range(0, (size / 2))[::-1]:
adjust_heap(lists, i, size)
def heap_sort(lists):
'''
堆排序(升序)【不稳定排序】
原理:
(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。
步骤:
1、构建堆
2、交换堆顶元素和最后一个元素的位置
时间复杂度:O(nlogn)
:param lists:
:return lists:
'''
size = len(lists)
build_heap(lists, size)
for i in range(0, size)[::-1]:
lists[0], lists[i] = lists[i], lists[0]
adjust_heap(lists, 0, i)
# 堆排序调用
heap_sort_list = heap_sort(lis)
print(heap_sort_list)

基数排序(桶排)

import math
def radix_sort(lists, radix=10):
'''
基数排序(桶排序)(升序)【稳定性排序】
基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O (nlog(r)m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的稳定性排序法。
时间复杂度:O(nlog(r)m) r是基数,m是堆数
:param lists:
:param radix:
:return lists:
'''
k = int(math.ceil(math.log(max(lists), radix)))
bucket = [[] for i in range(radix)]
for i in range(1, k+1):
for j in lists:
bucket[j/(radix**(i-1)) % (radix**i)].append(j)
del lists[:]
for z in bucket:
lists += z
del z[:]
return lists

3、斐波那契数列的python实现

【题目】 斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、…… 基于python用多种方式,生成费波拉契数列。

# (1)递归法 返回 idx 位的数值,缺点:只能返回某个值
def fib_recursion(idx):
if idx <= 2:
return 1
else:
return fib_recursion(idx-1) + fib_recursion(idx-2)
# (2)迭代法 返回 idx 位之前的fib数列
def fib_iteration(idx):
lst = []
n,a,b = 0,0,1
while n < idx:
lst.append(b)
a,b = b, a+b
n += 1
return lst
# (3)生成器法
def fib_generator(idx):
n,a,b = 0,0,1
while n < idx:
yield b
a,b = b, a+b
n += 1
if __name__ == '__main__':
idx = 6
numb = fib_recursion(idx)
print(numb)
lst = fib_iteration(idx)
print(lst)
lst1 = fib_generator(idx)
print(list(lst1))

4、丑数计算

转载自:https://blog.csdn.net/qq_34364995/article/details/80680354

遵循 CC 4.0 by-sa 版权协议

【题目】丑数是只包含质因数2,3,5的正整数(1也是特殊的丑数),请编写程序,找出第n个丑数

示例

输入:n=10
输出:12
解释:1,2,3,4,5,6,8,9,10,12 是前10个丑数

说明:1是丑数,n不超过1690

程序

class Solution:
def nthUglyNumber(self, n):
"""
原理:
动态规划思想。
后面的丑数一定是由前面的丑数乘以2、3或5得到。
所以第n个丑数一定是由前n-1个数中的某3个丑数(分别记为index2、index3、index5)分别乘以2、3或者5得到的数中的最小数,index2,index3,index5有个特点,即分别乘以2、3、5得到的数一定含有比第n-1个丑数大(可利用反证法:否则第n-1个丑数就是它们当中的一个)最小丑数,即第n个丑数由u[index2]*2、u[index3]*3、u[index5]*5中的最小数得出。让它们分别和第n个丑数比较,若和第n个丑数相等,则更新它们的值。注:一次最少更新一个值(如遇到第n个丑数是6时,index2和index3都要更新)。
:type n: int
:rtype: int
"""
if n <= 0:
return False
t1 = 0
t2 = 0
t3 = 0
res = [1]
while len(res) < n:
res.append(min(res[t1]*2, res[t2]*3, res[t3]*5))
if res[-1] == res[t1]*2:
t1 += 1
if res[-1] == res[t2]*3:
t2 += 1
if res[-1] == res[t3]*5:
t3 += 1
return res[-1]

5、如何不通过循环,输出1到100

【题目】如何不通过循环,输出1到100

def prints(n):
'''
可以通过递归替代循环
:param n:
:return:
'''
if (n > 0):
prints(n-1)
print(n)
if __name__ == '__main__':
prints(100)

6、如何对字符串进行反转

【题目】要求不使用任何系统方法,且时间复杂度最小

def reverse_str(input_str):
ch=list(input_str)
lens=len(ch)
i=0
j=lens-1
while i < j:
tmp= ch[i]
ch[i] =ch[j]
ch[j]=tmp
i+=1
j-=1
return ''.join(ch)
#tips 假如可以使用系统方法,如何实现?
new_str = old_str[::-1]

7、如何对单词反转

【题目】把"hello world" 反转成"world hello"

def reverse_word(test_str):
ch = test_str.split(" ")
lens = len(ch)
i = 0
j = lens - 1
while i < j:
tmp = ch[i]
ch[i] = ch[j]
ch[j] = tmp
i += 1
j -= 1
return ' '.join(ch)

8、两个列表如何生成一个对应的字典

【题目】l1=[‘Ben’, ‘Funn’, ‘Mike’, ‘Ronaldo’],l2= [17, 18, 18, 16],合并两个列表,生成 d = {‘Ben’: 17, ‘Funn’: 18, ‘Mike’: 18, ‘Ronaldo’: 16}

l1 = ['Ben', 'Funn', 'Mike', 'Ronaldo']
l2 = [17, 18, 18, 16]
d = dict(zip(l1, l2))
# 结果: d = {'Ben': 17, 'Funn': 18, 'Mike': 18, 'Ronaldo': 16}
# 反之,一个字典如何生成两个列表?
# 解法:用zip(*)函数,zip(*)会生成一个zip对象,即把[(a,b),(c,d),(e,f)]拆分成[(a,c,e)(b,d,f)],(此处只是伪代码帮助理解,实际上可能实现的过程并不是如此)
l1 = list(list(zip(*d.items()))[0])
l2 = list(list(zip(*d.items()))[1])
# 结果:
# l1 = ['Ben', 'Funn', 'Mike', 'Ronaldo']
# l2 = [17, 18, 18, 16]

9、统计字符串中每个字母出现的次数

【题目】统计字符串s='I love python'中,每个字母出现的次数

s = 'I love python'
# 解法1
from collections import Counter
d = dict(Counter(s))
# 结果:d = {'I': 1, ' ': 2, 'l': 1, 'o': 2, 'v': 1, 'e': 1, 'p': 1, 'y': 1, 't': 1, 'h': 1, 'n': 1}
# 假如说想要去掉空格的统计,只需要 d.pop(' ')即可,结果是:
# {'I': 1, 'l': 1, 'o': 2, 'v': 1, 'e': 1, 'p': 1, 'y': 1, 't': 1, 'h': 1, 'n': 1}
# 解法2
d = {}
for i in s:
d[i] = s.count(i)
# 结果:d = {'I': 1, ' ': 2, 'l': 1, 'o': 2, 'v': 1, 'e': 1, 'p': 1, 'y': 1, 't': 1, 'h': 1, 'n': 1}
# 解法3
from collections import defaultdict
s = 'I love python'
d = defaultdict(int)
for i in range(len(s)):
d[s[i]] += 1
# 结果:defaultdict(<class 'int'>, {'I': 1, ' ': 2, 'l': 1, 'o': 2, 'v': 1, 'e': 1, 'p': 1, 'y': 1, 't': 1, 'h': 1, 'n': 1})

10、对某英文文章的单词,进行词数统计

【题目】假设有一篇英文文章:English.txt,求出现次数最高的10个单词,并且这10个单词中每个单词出现的频数

# 采用正则表达式进行分词操作,再用collections库的Counter进行词频统计
import re
from collections import Counter
txt = open('English.txt', 'r').read()
#用正则表达式的split对txt整个字符串的单词进行分割(\W+表示特殊字符,差不多和[^a-zA-Z0-9_]等价,而\w+和[a-zA-Z0-9_]等价),split返回值是数组,用法和str.split差不多
res = re.split('\W+', txt)
all_counter = Counter(res) #用Counter统计出现单词的次数
top10 = all_counter.most_common(10) #对出现次数最多的10个单词进行统计
print(top10)
# 结果:[('in', 6), ('to', 5), ('subway', 5), ('the', 4), ('a', 3), ('app', 3), ('on', 3), ('city', 3), ('by', 3), ('have', 3)]
# tips:假如是中文文档,可以用jieba分词

11、字典排序

【题目】有一个学生分数的字典 d={"stu1":100, "stu2":90, "stu3":40},请按分数进行排序(从大到小)

# 思路:用sorted()函数去派去,sorted()函数适用于可迭代对象:sorted(iterable, cmd=None, key=None, reverse=False)
# cmp 是用于比较的函数,比较什么由key 决定
# key 是列表元素的某个属性或函数进行作为关键字,有默认值,迭代集合中的一项
# reverse = True 表示降序, reverse= False 表示升序
# 解法1 化为元祖,根据元祖中分数,去进行排序,缺点:key和value的值会颠倒
tup = zip(all_stu_dict.values(), all_stu_dict.keys())
rank = sorted(tup, reverse=True)
# 解法2 直接用sorted,并且制定规则来排序
rank = sorted(all_stu_dict.items(), key=lambda x:x[1], reverse=True)

12、如何快速找到多个字典的公共键

【题目】

第一轮:{‘C罗’:3, ‘格里兹曼’:2, ‘内马尔’:1, ‘博格巴’:1}

第一轮:{‘C罗’:2, ‘格里兹曼’:0, ‘内马尔’:0,’梅西’:2}

第一轮:{‘C罗’:4, ‘内马尔’:2, ‘库蒂尼奥’:2, ‘姆巴佩’:2}

统计每轮比赛都有进球的球员

d1 = {'C罗': 3, '格里兹曼': 2, '内马尔': 1, '博格巴': 1}
d2 = {'C罗': 2, '格里兹曼': 0, '内马尔': 0, '梅西': 2}
d3 = {'C罗': 4, '内马尔': 2, '库蒂尼奥': 2, '姆巴佩': 2}
# 解法1 迭代(效率最低)
shooter_list = []
for shooter in d1:
if shooter in d2 and shooter in d3:
shooter_list.append(shooter)
# 解法2 利用map分别取出每轮进球的球员名字,再用reduce对每轮都进球的球员进行取交集
all_shooters = map(dict.keys, [d1, d2, d3])
shooter_list = reduce(lambda a, b: a & b, all_shooters)

13、python的字典合并

主要思路:

  • 借助 dict(list(d1.items()) + list(d2.items()) 的方法,注意:list(d1.items()) + list(d2.items())拼成一个新的列表

  • 借助字典的 update() 方法:d1.update(d2)

  • 借助字典的dict(d1, **d2)方法

  • 借助字典的常规处理方法(采用迭代的方式)

14、python的socket编程

【解析】

服务端要做的工作:

  • 创建socket

  • 绑定端口

  • 监听端口

  • 接收消息

  • 发送消息

客户端要做的工作:

  • 创建socket

  • 连接socket

  • 发送消息

  • 接收消息

# 客户端
import socket
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(('127.0.0.1', 8000))
while True:
re_data = input()
client.send(re_data.encode("utf8"))
data = client.recv(1024)
print(data.decode("utf8"))
# 服务端
import socket
import threading
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(('0.0.0.0', 8000))
server.listen()
def handle_sock(sock, addr):
while True:
data = sock.recv(1024)
print(data.decode("utf8"))
re_data = input()
sock.send(re_data.encode("utf8"))
#获取从客户端发送的数据
#一次获取1k的数据
while True:
sock, addr = server.accept()
#用线程去处理新接收的连接(用户)
client_thread = threading.Thread(target=handle_sock, args=(sock, addr))
client_thread.start()

15、判断一个字符串中的括号是不是成对出现的

【题目】给出字符串 s = “12312{}{111{222}}”,判断字符串s中的 括号 是不是成对出现的

s = "12312{}{111{222}}"
def judge_brackets(target_str):
left_list = []
right_list = []
for i in target_str:
if i == '{' or i == '(' or i == '[':
left_list.append(i)
if (i == '}' or i == ')' or i == ']'):
if left_list != []:
left_list.pop()
else:
right_list.append(i)
if left_list != [] or right_list != []:
return "括号不是成对出现的"
return "括号是成对出现的"
p = judge_brackets(s)
print(p)

16、python的赋值、浅拷贝和深拷贝的区别

赋值 只是复制了新对象的引用,不会开辟新的内存空间。详细请看例子:

# 不可变对象
a = "abcde"
b = a
print(id(a), id(b))
# 结果: 2274644971848 2274644971848 两个变量的id是一致的
a = "xyz"
print((id(a), id(b)), (a, b))
# 结果:(1970541080680, 1970540237128) ('xyz', 'abcde'),因为字符串是不可变对象,改变之后要开辟新的内存空间,相当于创建了新的内存区块,并且a引用了新的内存区块,所以id这时候就不相等了。
# 可变对象
a = [1,2,3,4,5]
b = a
print(id(a), id(b))
# 结果:1861111211144 1861111211144
c.append(6)
print((id(a), id(b)), (a, b))
# 结果:(1861111211144, 1861111211144) ([1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6]),因为列表是可变对象,添加元素之后,并不会开辟新的内存区块,所以这时候两个变量仍然还是指向同一区块,id是相等的

浅拷贝 创建一个新的组合对象(所以id会不同),这个新对象与原对象共享内存中的子对象。能够拷贝所有元素的引用,但不拷贝元素的对象。

import copy
a = "abcde"
b = copy.copy(a)
print((id(a), id(b)), (a, b))
# 结果:(1911642247496, 1911642247496) ('abcde', 'abcde'),这里有一个十分重要的点,int、string等不可变对象,假如值特别小的话,python内部有一个优化机制,让其不会开辟新的内存空间,所以这种浅拷贝,id是相等的
a = [1,2,3,4,5]
b = copy.copy(a)
print((id(a), id(b)), (a, b))
# 结果:(2005329935816, 2005329935752) ([1, 2, 3, 4, 5], [1, 2, 3, 4, 5]),不可变对象的浅拷贝,拷贝了所有元素的引用,id是不相同的
a.append(6)
print((id(a), id(b)), (a, b))
# 结果:(2687650790856, 2687650790792) ([1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5]),因为 int 也是不可变对象,进行浅拷贝之后,新增元素也会开辟新的内存空间,所以两个变量的值和id都是不同的。
a = [1,2,3,4,[5,6,7]]
b = copy.copy(a)
print((id(a), id(b)), (a, b))
# 结果:(2773194341768, 2773194763784) ([1, 2, 3, 4, [5, 6, 7]], [1, 2, 3, 4, [5, 6, 7]])
a[4].append(8)
print((id(a), id(b)), (a, b))
# 结果:(2015617514888, 2015617937032) ([1, 2, 3, 4, [5, 6, 7, 8]], [1, 2, 3, 4, [5, 6, 7, 8]]),拷贝到元素的引用,a[4]指向一个数组(不可变对象),当这个元素的值改变时,没有开辟新的内存空间,所以这个元素还是指向同一个内存区块。

深拷贝 创建一个新的组合对象,同时递归地拷贝所有子对象,新的组合对象与原对象没有任何关联。虽然实际上会共享不可变的子对象,但不影响它们的相互独立性

import copy
a = "abcde"
b = copy.deepcopy(a)
print((id(a), id(b)), (a, b))
# 结果:(1684255592776, 1684255592776) ('abcde', 'abcde'),和浅拷贝一样
a = [1,2,3,4,5]
b = copy.deepcopy(a)
print((id(a), id(b)), (a, b))
# 结果:(1684258061768, 1684258061704) ([1, 2, 3, 4, 5], [1, 2, 3, 4, 5]),和浅拷贝差不多
a.append(6)
print((id(a), id(b)), (a, b))
# 结果:(1684258061768, 1684258061704) ([1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5]),和浅拷贝差不多
a = [1,2,3,4,[5,6,7]]
b = copy.deepcopy(a)
print((id(a), id(b)), (a, b))
# 结果:(1684258485064, 1684258061768) ([1, 2, 3, 4, [5, 6, 7]], [1, 2, 3, 4, [5, 6, 7]])
a[4].append(8)
print((id(a), id(b)), (a, b))
# 结果:(1684258485064, 1684258061768) ([1, 2, 3, 4, [5, 6, 7, 8]], [1, 2, 3, 4, [5, 6, 7]]),因为递归拷贝了子对象,所以这个例子可以看出和浅拷贝的区别所在,因为深拷贝递归的把元素的子元素也拷贝了一份,所以新的组合对象和原组合对象实际上看起来是不再有关联的

17、返回字符串中第一个不重复的字母和位置

def first_char(str):
d = {}
for i in range(len(str)):
# 累计字符的出现次数
if str[i] in d:
d[str[i]] += 1
# 只出现一次,key对应的value就记1次
else:
d[str[i]] = 1
for i in range(len(str)):
if d[str[i]] == 1:
return '第一个不重复的字符串是{},索引是{}'.format(str[i], i)
return "没有不重复的字符串"
if __name__ == '__main__':
s = "wwqqoogg"
res = first_char(s)
print(res)

18、求一个数字列表里,相邻两数乘积最高的值,及这两个数分别是多少?

【题目】给出L = [2, 4, 6, 3, 9, 11, -12] , 求相邻两数乘积最大的值,并返回这两个相乘的数。

L = [2, 4, 6, 3, 9, 11, -12]
def multi_max(lis):
L1 = []
for i in range(1, len(lis)):
j = i - 1
multi = lis[i] * lis[j]
L1.append((multi, lis[i], lis[j]))
# max函数是取第一个元素做比较,也就是说按multi最大来排
return max(L1)
multi, left, right = multi_max(L)
print(multi, left, right)

19、一行代码实现字典的key和value反转

【题目】d = {"name":1, "age":2},反转字典 d,反转成{1:"name", 2:"age"}

d = {"name":1, "age":2}
d1 = {age:name for name,age in d.iterms()}

20、如何求字符串例的最长回文子串

待施工

21、python如何实现单例模式

# 装饰器中@语法糖的意思:@foo <=等价=> foo = decorator(foo)
instances = {}
def singleton(cls):
def get_instance(*args, **kwargs):
cls_name = cls.__name__
if not cls_name in instances:
instance = cls(*args, **kwargs)
instances[cls_name] = instance
return instances[cls_name]
return get_instance
@singleton
class User:
_instance = None
def __init__(self, name):
self.name = name

22、为什么模块称为天然的单例模式?

更多:http://funhacks.net/2017/01/17/singleton/

解释:

因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。

# mysingleton.py
class My_Singleton(object):
def foo(self):
pass
my_singleton = My_Singleton()
from mysingleton import my_singleton
my_singleton.foo()

24、Python处理排列组合

排列组合数的计算公式:

排列

(考虑顺序,比如(1,2)不等于(2,1))

计算全排列有多少种情况:A23 = 3!/(3-2)! = 6

组合

(不考虑顺序,比如(1,2)和(2,1)都只算一种)

计算组合有多少种情况:C23 = 3!/(3-2)!2! = 3

用库:

计算排列组合各有多少种情况

from scipy.special import comb, perm
# 排列
perm(3, 2)
# 输出 => 6.0
# 组合
comb(3, 2)
# 输出 => 3.0

计算排列组合,全部结果展开

from itertools import combinations, permutations
permutations([1, 2, 3], 2)
// <itertools.permutations at 0x7febfd880fc0>
# 可迭代对象
# 计算排列结果
list(permutations([1, 2, 3], 2))
# 输出 => [(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)]
# 计算组合结果
list(combinations([1, 2, 3], 2))
# 输出 => [(1, 2), (1, 3), (2, 3)]

25、将某个数字列表中的元素拼成一个最大的数

例如给定:lists = [98, 77, 981, 2221, 3322],定义一个方法,输出989817733222221

# -*- coding:utf-8 -*-
def spile_max(lists):
'''
利用冒泡排序去解决,比较相邻两数,比如98和77,可以组成7798和9877,
9877>7798所以,98在77前面
'''
for i in range(len(lists) - 1):
for j in range(len(lists) - i - 1):
if int(str(lists[j]) + str(lists[j + 1])) < int(str(lists[j + 1]) + str(lists[j])):
lists[j], lists[j + 1] = lists[j + 1], lists[j]
return lists
if __name__ == '__main__':
lists = [98, 77, 981, 2221, 3322]
arr = spile_max(lists)
print(arr)