如下面的代码,通过如下的形式,从迭代器 prices.items()
中把键值对一个个取出来,然后分成两个参数 key
,value
,再判断是否满足 value>100
,若满足则把这两个参数赋给 for
左边的两个变量(刚好也是同名的) key
和value
。而for
左边的两个参数刚好用冒号连起来,加上外面的花括号,说明最后返回的结果也是一个字典。
这个形式其实只是把多行的代码压缩成一行代码,逻辑不复杂,不过却能把逻辑直观地展现,熟悉之后大家可以习惯用这种写法,能让代码看起来没那么冗余。
prices = {
'AAPL': 191.88,
'GOOG': 1186.96,
'IBM': 149.24,
'ORCL': 48.44,
'ACN': 166.89}
# 用for循环提取出键和值,并找出价格大于100键值对,形成一个新的字典
prices2 = {key: value for key, value in prices.items() if value > 100}
print(prices2)
2.嵌套列表
注意嵌套列表还是一个列表,只是列表中的元素也还是列表(向量),含有二维的信息。平时在处理的时候可能常常会忘记自己生成的数据的类型而用错索引方式。
一般像这种数组的操作,最好就是用 Pandas
的 array
数组,数组就有比如 3行2列
这种“立体”结构。用的索引方式可以用 .iloc[]
。
names = ['关羽', '张飞', '赵云', '马超', '黄忠']
courses = ['语文', '数学', '英语']
# scores = [[None] * len(courses) for _ in range(len(names))] # 这种写法也可以
scores = [[None] * len(courses)] * len(names)
for row, name in enumerate(names):
for col, course in enumerate(courses):
scores[row][col] = float(input(f'请输入{name}的{course}成绩: '))
print(scores)
堆是一种基础的数据结构,堆排序是指利用堆这种数据结构所设计的一种排序算法。它的效率与其他的快速排序等排序算法相当,但比后者更加稳定,也更节省空间。
而在Python中没有专门提供堆这种数据类型,而是用一个高级模块 heapq(heap queue)
来实现堆排序。注意模块的方法所需传入参数都为迭代器对象,这里用 list
举例。
"""
从列表中找出最大(nlargest)的或最小(nsmallest)的 n 个元素
"""
import heapq
list1 = [34, 25, 12, 99, 87, 63, 58, 78, 88, 92]
list2 = [
{'name': 'IBM', 'shares': 100, 'price': 91.1},
{'name': 'AAPL', 'shares': 50, 'price': 543.22},
{'name': 'FB', 'shares': 200, 'price': 21.09},
{'name': 'HPQ', 'shares': 35, 'price': 31.75},
{'name': 'YHOO', 'shares': 45, 'price': 16.35},
{'name': 'ACME', 'shares': 75, 'price': 115.65}
]
print(heapq.nlargest(3, list1))
print(heapq.nsmallest(3, list1))
print(heapq.nlargest(2, list2, key=lambda x: x['price']))
print(heapq.nlargest(2, list2, key=lambda x: x['shares']))
lambda
在这里表示匿名函数,可以理解为,循环一个个把要排序的对象取出来,也就是这里的 x
,但是每个对象都有好几个属性,我到底要用哪个属性作为我排序的依据(key
)呢,以价格属性为依据 price
,那体现在这个字典结构中,就是 x['price']
。以此类推,如果 x
是个列表,但是我们要以列表的第2个数作为排序依据,那就写为 key = lambda x: x[1]
。
4.迭代器操作
循环器(iterator)是对象的容器,包含有多个对象。像我们平时接触的列表 list
、字符串 string
等,都是一个可迭代的对象(它们并不是迭代器对象,只是可迭代,我有时候会习惯性地称为迭代器),这些都可以用 iter
转换为一个迭代器。通过循环能读取可迭代对象中的内容。而 itertools
模块提供了丰富的灵活的操作循环器的工具。其中,itertools
只是生成一个无限循环对象,并不是真的在内存中生成这么多内容,当使用 for
循环打印时,才不断地循环输出循环器的内容。就像下面的 len(order_3)
一样,如果在没开始循环前,就想读取循环器的长度就会报错,也印证了我们关于循环器本身只是存储了循环信息,并没有真的存储了循环内容的猜想,只有在循环(for
)当中,才会将内容生成。
"""
迭代工具模块
"""
import itertools
# 产生无限循环序列
order_1 = itertools.cycle(('A', 'B', 'C'))
for _ in order_1:
print(i) # 反复输出 ABCABCABCA...
# 产生ABCD和123的笛卡尔积
# 生成 ('A','1'),('A','2'),('A'.'3'),('B','1')...
order_2 = itertools.product('ABCD', '123')
# 产生ABCD四个字母的全排列
# 每种排序对象都是一个元组
order_3 = itertools.permutations('ABCD')
# 如果想要知道全排序的长度,就会报错
print(len(order_3))
# 产生ABCDE中任意三个元素的组合
itertools.combinations('ABCDE', 3)
对于产生无限序列循环器,如果只想输出其中的符合条件的部分数,可以用 takewhile(predicate, iterable)
。其中两个参数,先说后面的 iterable
就是我们生成的无限序列循环器对象,而前面的呢,故名思意就是 while
即什么时候 take
,就是特定条件下才出发循环打印,它可以时自定义函数,也可以是匿名函数,返回的值是布尔类型,就是每次循环器的时候都判断一下,是否要继续循环。
import itertools
natuals = itertools.count(1)
# 匿名函数的方式
takewhile_ = itertools.takewhile(lambda x: x <= 10, natuals)
# 自定义函数的方式
def test_func(x):
return(x<=10)
takewhile_ = itertools.takewhile(test_func, natuals)
这里的 x
可以理解为每次循环将要打印出来的那个值,如果满足条件,则打印,不满足则终止循环。除了用匿名函数,也可以用自定义函数,注意调用时不用加上参数x
,因为它并不存在,只是在每次循环的时候会出现。