Python--习题

  • 1,给定列表,找出第二大的数
  • *方法一 找极值再删除(极不推荐)*
  • *方法二 分治算法*
  • 2,打印成绩倒数第二的同学名字
  • 3,使用zip(*[iter(s)]*5)按照指定长度5,截取字符串
  • 4,计数类collections.Counter
  • 5,统计字符串中字母出现次数 并按频次排序
  • 6,将数据切分成各重叠段,统计各段数值,重叠次数
  • *方法一,我的无脑操作*
  • *方法二,from itertools import groupby*
  • 7,左耳进右耳出队列collections.deque
  • 8,复合型一键多值字典
  • 9,字典排序 operator.itemgetter(1)代替 lambda x:x[1]
  • 10,创建字典列表,itertools.groupby根据字典value值分组


1,给定列表,找出第二大的数

方法一 找极值再删除(极不推荐)

arr = [1, 2, 3, 23, 7, 37, 18, 37, 24, 37, 2]
max_index = [i for i, val in enumerate(arr) if val == max(arr)]
print(max_index)
index = 0
for i in max_index:
    arr.remove(arr[i-index])
    index += 1
print(arr)
print(max(arr))

输出

max_index =  [5, 7, 9]
arr =    [1, 2, 3, 23, 7, 18, 24, 2]
max(arr) =   24

方法二 分治算法

  1. 序列分解,小值序列,中间值,大值序列
  2. 逐层递归,输出时即为小值序列长度等于2时的情况
def partition(lst):
    mid = lst[0]
    low = [i for i in lst[1:] if i<=mid]
    high =[i for i in lst[1:] if i> mid]
    return low,mid,high

def select(lst,k):
    low,mid,high = partition(lst)
    if len(high) == k:
        return mid
    elif len(high) > k:
        return select(high,k)
    elif len(high) < k:
        return select(low,k-len(high)-1)
import random
# lst = [random.randint(1,20) for i in range(10)]
lst = [1, 2, 3, 23, 7, 37, 18, 37, 24, 37, 2]
lst = list(set(lst))
print(lst)
print(select(lst,1))

输出

[1, 2, 3, 37, 7, 18, 23, 24]
24

2,打印成绩倒数第二的同学名字

name = ['Harry', 'Berry', 'Tina', 'Akriti', 'Harsh']
score = [37.21, 37.21, 37.2, 41, 39]
name_score = {name: score for name, score in zip(name, score)}
min_name = []
for i, i_score in name_score.items():
    if i_score == min(name_score.values()):
        min_name.append(i)
for i in min_name:
    del name_score[i]
min_name_2 = [i for i, i_score in name_score.items() if i_score == min(name_score.values())]
print('\n'.join(min_name_2))

输出

Harry
Berry

3,使用zip(*[iter(s)]*5)按照指定长度5,截取字符串

s = 'abcdefghijklmnopqrstuvwxyz'
# s = [1,2,3,4,5]
# a = zip(*[iter(s)]*3)
# a = zip(*iter(s),*iter(s),*iter(s))
print(*s)
print(*iter(s))
print(iter(s))    #迭代器
print(*[iter(s)]) #迭代器
# a = zip(*[iter(s)])
a = zip(*[iter(s)]*5)
for i in a:
    print(i)

输出

a b c d e f g h i j k l m n o p q r s t u v w x y z
a b c d e f g h i j k l m n o p q r s t u v w x y z
<str_iterator object at 0x00000225317ABA58>
<str_iterator object at 0x00000225317ABA58>
('a', 'b', 'c', 'd', 'e')
('f', 'g', 'h', 'i', 'j')
('k', 'l', 'm', 'n', 'o')
('p', 'q', 'r', 's', 't')
('u', 'v', 'w', 'x', 'y')

4,计数类collections.Counter

from collections import Counter
string = 'abbcccdddd'
print(Counter(string)) #Counter({'d': 4, 'c': 3, 'b': 2, 'a': 1})

5,统计字符串中字母出现次数 并按频次排序

from collections import Counter,OrderedDict
class My_class(Counter,OrderedDict):pass

string = 'abbcccdddd'
print(list(map(str,string)))
print(sorted(string))
print(type(sorted(string)))
print(type(My_class(sorted(string)).most_common(4)))
[print(*c) for c in My_class(sorted(string)).most_common(4)]
#
# My_class 继承自 Counter,OrderedDict,字符串列表作为参数,生成对象
# 调用其most_common(4)方法,返回一个列表,取前四名 c为双元素元组(value,count)

输出

['a', 'b', 'b', 'c', 'c', 'c', 'd', 'd', 'd', 'd']
['a', 'b', 'b', 'c', 'c', 'c', 'd', 'd', 'd', 'd']
<class 'list'>
<class 'list'>
d 4
c 3
b 2
a 1

6,将数据切分成各重叠段,统计各段数值,重叠次数

方法一,我的无脑操作

import copy
num = 12233344445555567788899991
num_list = list(map(int,str(num)))
str_list1 = list(str(num))
str_list2 = copy.deepcopy(str_list1)
print(str_list1)
j = k = 0
for i in range(len(str_list1)-1):
    if str_list1[i]!=str_list1[i+1]:
        j = i + k
        str_list2.insert(j+1,'w')
        k +=1
print('str_list2 =   ',str_list2)
# num_split = ''.join(list(map(str,num_list)))
num_split = ''.join(str_list2)#选择上面一行也可,join([str])添加字符串列表再压缩
print('num_split =  ',num_split)
num_list_str = num_split.split('w')#list.split('') 返回一个字符串列表
print('num_list_str = ',num_list_str)
result = []
for i in range(len(num_list_str)):
    result.append((int(num_list_str[i][0]),len(num_list_str[i])))
print('\n',result)

输出

num_split =   1w22w333w4444w55555w6w77w888w9999w1
num_list_str =  ['1', '22', '333', '4444', '55555', '6', '77', '888', '9999', '1']
 [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 1), (7, 2), (8, 3), (9, 4), (1, 1)]

方法二,from itertools import groupby

num = 12233344445555567788899991
str_list1 = list(str(num))
from itertools import groupby
print(*[(len(list(c)), int(k)) for k, c in groupby(str_list1)])

输出

(1, 1) (2, 2) (3, 3) (4, 4) (5, 5) (1, 6) (2, 7) (3, 8) (4, 9) (1, 1)

7,左耳进右耳出队列collections.deque

from collections import deque
#
# lines =>> f
# pattern :  所要查找的字符
# history :  保留的历史长度,即双向队列的容纳长度
#
#
# 生成器  yield line, previons_line
# 查找某个字符,打印其所在行
def search(lines, pattern, history=5):
    previons_line = deque(maxlen=history)
    for line in lines:
        if pattern in line:
            previons_line.append(line)
            yield line, previons_line
if __name__ == '__main__':
    with open('nun.txt') as f:
        for line, prevlines in search(f, 'w', 4):
            for pline in prevlines:
                print(pline)
            print('-'*20)

8,复合型一键多值字典

# 复合型字典
# 一键多值,value为 list set tuple
from collections import defaultdict
dic = defaultdict(list)
dic['a'].append(1)
dic['a'].append(2)
dic['b'].append(3)
print(dic)	#defaultdict(<class 'list'>, {'a': [1, 2], 'b': [3]})

9,字典排序 operator.itemgetter(1)代替 lambda x:x[1]

import random
key_lst = [chr(i) for i in range(ord('A'),ord('D')+1)]
val_lst = list(range(4))
random.shuffle(val_lst)
dic = {key:value for key,value in zip(key_lst,val_lst)}
print(dic)
lst = list(dic.items())
print(lst)
##############################################几种字典排序方法
#
# 现在需求:
#           字典按照key 或者value排序
#
# 解决方法:

#1 字典转化为双元组列表,
# lst.sort(key = lambda x:x[1])
# lst = sorted(lst,key=lambda x:x[1])# 上面一行也可

#2 使用函数 itemgetter(1) ==>>  lambda x:x[1]
from operator import itemgetter
func = itemgetter(1)
lst.sort(key=func)
#############################几种字典排序方法

dic = dict(lst)
print(dic)

输出

{'A': 0, 'B': 3, 'C': 2, 'D': 1}
[('A', 0), ('B', 3), ('C', 2), ('D', 1)]
{'A': 0, 'D': 1, 'C': 2, 'B': 3}

10,创建字典列表,itertools.groupby根据字典value值分组

import random
lst = []
str1 = ['W','S','E','N']
str2 = ['CLARK','58ARK']
key_ = ['address','data']

for i in range(8):
    dic = dict.fromkeys(key_)
    dic[key_[0]] = str(random.randint(1000,9999)) + ' '+random.choice(str1)+ ' ' + random.choice(str2)
    dic[key_[1]] = str(2018) + '/' + str(random.randint(1,12)) + '/' + str(random.randint(1,28))
    lst.append(dic)
[print(i)for i in lst]

from operator import itemgetter
from itertools import groupby
lst.sort(key = itemgetter('data'))#分组之前必须排序,列表元素的键值
for data,item in groupby(lst,key=itemgetter('data')):
    print(data)

输出

{'address': '4852 S CLARK', 'data': '2018/10/8'}
{'address': '9306 S CLARK', 'data': '2018/2/1'}
{'address': '7652 W CLARK', 'data': '2018/8/5'}
{'address': '8189 N 58ARK', 'data': '2018/8/24'}
{'address': '9939 S 58ARK', 'data': '2018/11/12'}
{'address': '2648 E 58ARK', 'data': '2018/3/12'}
{'address': '2244 N CLARK', 'data': '2018/4/27'}
{'address': '4150 E CLARK', 'data': '2018/10/10'}
2018/10/10
2018/10/8
2018/11/12
2018/2/1
2018/3/12
2018/4/27
2018/8/24
2018/8/5