Python数据结构与算法相关问题与解决技巧
1.如何在列表, 字典, 集合中根据条件筛选数据¶
In [1]:
from random import randint
In [2]:
data = [randint(-10,10) for _ in range(10)]
In [3]:
data
Out[3]:
In [4]:
# 筛选出列表中大于0的元素
# 使用filter函数
list(filter(lambda x:x>=0,data))
Out[4]:
In [5]:
# 列表解析
[x for x in data if x >= 0]
Out[5]:
In [6]:
timeit list(filter(lambda x:x>=0,data))
In [7]:
timeit [x for x in data if x >= 0]
In [8]:
# 字典解析
d = {x:randint(60,100) for x in range(1,21)}
In [9]:
d
Out[9]:
In [10]:
{k:v for k,v in d.items() if v > 90 }
Out[10]:
In [11]:
# 集合解析
s = set(data)
In [12]:
s
Out[12]:
In [13]:
{x for x in s if x % 2 == 0}
Out[13]:
2.如何为元组中的每个元素命名, 提高程序可读性¶
In [14]:
#方案一,定义一系列数值常量
NAME,AGE,SEX,EMAIL = range(4)
In [15]:
student = ('Tom','16','male','tom@gmail.com')
In [16]:
student[NAME]
Out[16]:
In [17]:
#方案二,使用namedtuple
from collections import namedtuple
In [18]:
Student = namedtuple('Student',['name','age','sex','email'])
In [19]:
#位置传参
s = Student('Tom','16','male','tom@gmail.com')
In [20]:
s
Out[20]:
In [21]:
#关键字传参
s2 = Student(name='Tom',age='16',sex='male',email='tom@gmail.com')
In [22]:
s2
Out[22]:
In [23]:
s.name
Out[23]:
In [24]:
s.email
Out[24]:
In [25]:
isinstance(s,tuple)
Out[25]:
3.如何统计序列中元素的出现频度¶
In [26]:
from random import randint
In [27]:
data = [randint(0,20) for _ in range(30)]
In [28]:
data
Out[28]:
In [29]:
#fromkeys:用于创建并返回一个新的字典。两个参数:第一个是字典的键,第二个(可选)是传入键的值,默认为None。
c = dict.fromkeys(data,0)
In [30]:
c
Out[30]:
In [31]:
for x in data:
c[x] += 1
In [32]:
c
Out[32]:
In [33]:
# 使用Counter
from collections import Counter
In [34]:
c2 = Counter(data)
In [35]:
c2
Out[35]:
In [36]:
#找出频率出现最高的3个元素
c2.most_common(3)
Out[36]:
In [37]:
import re
In [38]:
txt = open('Alice.txt').read()
In [39]:
c3 = Counter(re.split('\W+',txt))
In [40]:
c3
Out[40]:
In [41]:
c3.most_common(10)
Out[41]:
4.如何根据字典中值的大小, 对字典中的项排序¶
In [42]:
sorted([9,3,1,67,6])
Out[42]:
In [43]:
from random import randint
In [44]:
d = {x:randint(60,100) for x in 'xyzabc'}
In [45]:
d
Out[45]:
In [46]:
d.keys()
Out[46]:
In [47]:
d.values()
Out[47]:
In [48]:
#方案一:利用zip将字典转换成元组进行排序
sorted(zip(d.values(),d.keys()))
Out[48]:
In [49]:
d.items()
Out[49]:
In [50]:
#方案二:传递sorted函数的key参数
sorted(d.items(),key=lambda x:x[1])
Out[50]:
5.如何快速找到多个字典中的公共键(key)¶
In [51]:
from random import randint,sample
In [52]:
from random import randint,sample
In [53]:
# 取样
sample('abcdef',3)
Out[53]:
In [54]:
sample('abcdef',randint(3,6))
Out[54]:
In [55]:
# 找出s1,s2,s3中都存在的key
# 方案一:遍历
s1 = {x:randint(1,4) for x in sample('abcdef',randint(3,6))}
In [56]:
s1
Out[56]:
In [57]:
s2 = {x:randint(1,4) for x in sample('abcdef',randint(3,6))}
In [58]:
s3 = {x:randint(1,4) for x in sample('abcdef',randint(3,6))}
In [59]:
s2
Out[59]:
In [60]:
s3
Out[60]:
In [61]:
res = []
for k in s1:
if k in s2 and k in s3:
res.append(k)
In [62]:
res
Out[62]:
In [63]:
# 方案二:使用集合
s1
Out[63]:
In [64]:
s1.keys()
Out[64]:
In [65]:
s2.keys()
Out[65]:
In [66]:
s1.keys() & s2.keys() & s3.keys()
Out[66]:
In [67]:
# 方案三:使用map和reduce
# Python3里,map返回的结果是迭代器(iterator)
list(map(dict.keys,[s1,s2,s3]))
Out[67]:
In [68]:
from functools import reduce
# reduce() 函数会对参数序列中元素进行累积。
reduce(lambda a,b:a & b,map(dict.keys,[s1,s2,s3]))
Out[68]:
6.如何让字典保持有序¶
In [69]:
d = {}
d['Tom'] = (1,35)
d['Bob'] = (2,37)
d['Kate'] = (3,45)
In [70]:
d
Out[70]:
In [71]:
# python3.6之后字典有序,按照数据存入的顺序
for k in d:
print(k)
In [72]:
# 有序字典OrderedDict
from collections import OrderedDict
d = OrderedDict()
In [73]:
d['Tom'] = (1,35)
d['Bob'] = (2,37)
d['Kate'] = (3,45)
for k in d:
print(k)
In [74]:
from time import time
from random import randint
from collections import OrderedDict
d = OrderedDict()
players =list('ABCDEFGH')
start = time()
for i in range(8):
'''模拟选手比赛消耗时间并存入字典中'''
input()
p = players.pop(randint(0,7-i))
end = time()
print(i + 1, p, end - start,sep=' ')
d[p] = (i + 1, end - start)
print('-' * 30)
for k in d:
print(k, d[k])
7.如何实现用户的历史记录功能(最多n条)¶
In [75]:
from collections import deque
# 创建双向队列
q = deque([], 5)
In [76]:
q
Out[76]:
In [77]:
q.append(1)
q.append(2)
q.append(3)
q.append(4)
q.append(5)
q
Out[77]:
In [78]:
q.append(6)
q
Out[78]:
In [79]:
from random import randint
from collections import deque
N = randint(0, 100)
history = deque([], 5)
def guess(k):
if k == N:
print('Right')
return True
if k < N:
print('%s is less-than N' % k)
else:
print('%s is greater-than N' % k)
return False
while True:
line = input('Please input a number:')
if line.isdigit():
k = int(line)
history.append(k)
if guess(k):
break
elif line == 'history' or line == 'h':
print(list(history))
In [80]:
import pickle
In [81]:
q
Out[81]:
In [82]:
# 将数据存入文件
pickle.dump(q,open('history','wb'))
In [83]:
# 读取文件
q2 = pickle.load(open('history','rb'))
In [84]:
q2
Out[84]: