编写代码时除了要准确地实现功能之外,还要考虑代码的优化,尽量找到一种更快、更好的方法实现预定功能。Python 字典和集合都使用哈希表来存储元素,元素查找速度非常快,关键字 in 作用于字典和集合时比作用于列表要快得多。
import random, time
a = list(range(10000))
b = tuple(range(10000))
c = set(range(10000))
d = dict(zip(range(10000), range(10000)))
x = random.randint(0, 9999)
for i in (d, c, b, a):
start = time.time()
for j in range(10000000):
g = x in i
print(type(i), time.time() - start)
对于成员测试运算符 in,列表地效率远远不如字典和集合,并且随着序列的变长,列表的查找速度越来越慢,而字典和集合基本不受影响。
可以使用集合快速提取序列中的单一元素,即提取出序列中所有不重复的元素。
# 使用传统方式
import random
# 生成100个介于0~9999之间的随机整数
x = [random.choice(range(10000)) for i in range(100)]
g = []
for i in x:
if i not in g:
g.append(i)
# 使用集合,只需要一行代码
g = set(x)
集合中的元素不允许重复,Python 集合的内部实现为此做了大量相应的优化,添加元素时如果已经存在重复元素则自动忽略。
返回指定范围内一定数量的不重复数字
import random
def randomNumbers(number, start, end):
# 使用集合来生成 number 个介于 start 和 end 之间的不重复随机数
data = set()
while len(data) < number:
element = random.randint(start, end)
data.add(element)
return data
print(randomNumbers(10, 20, 80))
可以直接使用 random 模块的 sample() 函数。random 模块的 samle() 函数只支持列表、元组、集合、字符串和 range 对象,不支持字典以及 map、zip、enumerate、filter 等惰性求值的迭代对象。
import random
print(random.sample(range(1000), 10)) # 在指定分布中选取不重复的元素
1 下面的两段代码测试指定列表中是否包含非法数据,很明显第二段使用集合的代码更高效一些。
import random
color = ('red', 'green', 'blue')
s = ('red', 'green', 'blue', 'white', 'black')
colors = [random.choice(s) for i in range(10000)]
for i in colors: # 遍历列表中的元素并逐个判断
if i not in color:
print('error: ', i)
break
if set(colors) - set(color): # 转换为集合之后再比较
print('error')
2 假设已有若干用户名字及其喜欢的电影清单,现有某用户,已看过并喜欢一些电影,现在想找个新电影看,又不知道看什么好。根据已有数据,查找与该用户爱好最相似的用户,也就是看过并喜欢的电影与该用户最接近的用户,然后从那个用户喜欢的电影中选取一个当前用户还没看过的电影,然后推荐。
from random import randrange
# 其他用户喜欢的电影清单
data = {'user' + str(i): {'film' + str(randrange(1, 10)) for j in range(randrange(15))}
for i in range(10)}
# 待测用户曾经看过并感觉不错的电影
user = {'film1', 'film2', 'film3'}
# 查找与待测用户最相似的用户和他喜欢的看的电影
similarUser, films = max(data.items(), key=lambda i: len(i[1] & user))
print('history data:')
for u, f in data.items():
print(u, f, sep=' : ')
print('similarUser: ', similarUser)
print('films: ', films)
print('recommend: ', films-user)