Python数据结构:列表,数组,生成器,元祖等。
1. list列表
列表对象是可直接相加的。相当于两个列表合并。
combined = zeros + letters
list(range(10))
可以将literable转换成list
letter[::2]
每两个元素返回 lette[;;-1]倒序
list解包
全部提取
numbers = [1, 2, 3]
first, second, third = numbers
仅提取前两个
numbers = [1, 2, 3, 4, 4, 4, 4, 4, 4]
first, second, *other = numbers
for循环和enumerate连用
提取列表index和内容。
letters = ["a", "b", "c"]
for index, letter in enumerate(letters):
print(index, letter)
增删列表内容
letter = ["a", "b", "c"]
# Add
letters.append("d")
letters.insert(0, "-")
# Remove
letters.pop(0)
letters.remove("b")
del letters[0:3]
letters.clear()
print(letters)
找items
print(letters.count("d"))
if "d" in letters:
print(letters.index("d"))
排序
numbers = [3, 51, 2, 8, 6]
numbers.sort(reverse=True)
sorted(numbers)
sorted返回新的列表。sort在原列表修改
对复杂的列表如何定义基于什么排序(下面代码可以用匿名函数简化)
items = [
("Product1", 10),
("Product2", 9),
("Product3", 12)]
def sort_item(item):
return item[1]
items.sort(key=sort_item
##2. lambda,map,filter,列表推导式
匿名函数语法:lambda parameters:expression
items = [
("Product1", 10),
("Product2", 9),
("Product3", 12)
]
prices = list(map(lambda item: item[1], items))
#[10, 9, 12]
items.sort(key=lambda item: item[1])
print(items)
#[('Product2', 9), ('Product1', 10), ('Product3', 12)]
map
map(func,literable
:返回的是一个map对象,可以用list转换成列表
map(func, *iterables)
:对iterables中的每个参数执行函数,得到一个map对象,是一个iterator。
filter
filter(func,literable)
func返回布尔值
items = [
("Product1", 10),
("Product2", 9),
("Product3", 12)
]
x = list(filter(lambda item: item[1] ≥ 10, items))
print(x)
# [('Product1', 10), ('Product3', 12)]
list comprehension:列表推导式
推荐用这个。而不是map和filter
语法:[expression for item in items]
# map和等同的列表推导式
prices = list(map(lambda item: item[1], items))
prices = [item[1] for item in items]
# filter和等同的列表推导式
filtered = list(filter(lambda item: item[1] ≥ 10, items))
filtered = [item for item in items if item[1] ≥ 10]
# else
new = [0 if item[1]≥10 else 0 for item in items]
3. zip
zip(iter1 [,iter2 [...]]) --> zip object
Return a zip object whose .next() method returns a tuple where the i-th element comes from the i-th iterable argument.
list1 = [1, 2, 3]
list2 = [10, 20, 30]
print(list(zip("abc", list1, list2)))
#[('a', 1, 10), ('b', 2, 20), ('c', 3, 30)]
4. stacks&queues
stack:LIFO 后进先出
queues:FIFO 先进先出
from collections import deque
queue = deque([])
queue.append(1)
queue.append(2)
queue.append(3)
queue.popleft()
print(queue)
if not queue:
print("empty")
5. tuple:括号可省略,但要有逗号
和list的区别是,tuple不可修改
tuple可用于快速交换变量的值
x, y = y, x
6. array
指定类别。当处理十万级的数据时可用
from array import array
numbers = array("i", [1, 2, 3])
i:signed integer
7. set
集合 大括号 是unordered list,没有重复值,没有index
numbers = [1, 1, 2, 3, 4]
first = set(numbers)
second = {1, 5}
print(first | second)
print(first & second)
print(first - second)
print(first ^ second)
if 1 in first:
print("yes")
8. 字典
下面两种创建中, 第二种方法更好
point = {"x": 1, "y": 2}
point = dict(x=1, y=2)
get method: 如果不存在则默认返回null。如果设定第二个参数,则返回第二个参数的值
print(point.get("a", 0))
删除某个成员 del point["x"]
循环字典
for key in point:
print(key, point[key])
items返回的是tuple,因此可以直接解包
for key,value in point.items():
print(key, value)
comprehension: 列表,set,字典都可以用推导式
values = {x: x * 2 for x in range(5)}
defaltdict
https://www.jianshu.com/p/bbd258f99fd3
from collections import defaultdict
STATS = defaultdict(lambda: defaultdict(str))
一个这样的字典,如何按key sort呢
s = sorted(STATS.items())
for i in s:
print(i[0])
s成为一个排序后的list,list的每个成员是一个tuple,包括之前字典的key和value。
9. 生成器
用在创建的列表特别的大。不会将全部的值存在内存中,而是每个循环生成一个值。
和列表生成器在写法上的区别就是一个是中括号,一个是圆括号。
generator保存的是算法,每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。正常使用是有for循环。
generator非常强大。如果推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以用函数来实现。把print改成yield就可以
def fib(x):
n = 0
a, b = 0, 1
while n < x:
yield b
a, b = b, a+b
n = n + 1
g = fib(6)
print(next(g))
for i in g:
print(i)
这里的fib就是一个生成器,g是一个生成器对象。可用for循环访问全部的结果。
code:单位bytes
from sys import getsizeof
values = (x * 2 for x in range(100000))
print("gen:", getsizeof(values))
values = [x * 2 for x in range(100000))
print("list:", getsizeof(values))
#gen: 120
#list: 824464
杨辉三角
import operator
def triangles():
L1 = [1]
while True:
yield L1
L_former = [0] + L1
L_last = L1 + [0]
L1 = list(map(operator.add, L_former, L_last))
tri = triangles()
print(next(tri))
print(next(tri))
print(next(tri))
print(next(tri))
print(next(tri))
#[1]
#[1, 1]
#[1, 2, 1]
#[1, 3, 3, 1]
#[1, 4, 6, 4, 1]
生成器函数需要一个loop,每次yield一个loop。
map函数,实现两个list的相加运算。这里用到了operator模块。
10. 解包:星号 可用于解包任何literable
numbers = [1, 2, 3]
print(*numbers)
print(1, 2, 3)
创建list将range obj解包。
values = list(range(5))
values = [*range(5)]
print(values)
字典用两个星号。重复的key,后面的覆盖前面的
first = {"x": 1}
second = {"x": 10, "y": 2}
combined = {**first, **second, "z": 1}
print(combined)
11. 练习
- 目的:一个句子中最常出现的字符
- key-value pair用字典。列表推导式,重复的元素,后面的覆盖前面的。
字典是unordered list,因此不能用sort。需要将其转换成tuple list。
pprint 可以选择一行显示几个 - code
from pprint import pprint
sentence = "This is a common question."
char_count = {char: sentence.count(char) for char in sentence}
char_count_sorted = sorted(
char_count.items(), key=lambda item:item[1], reverse=True)
pprint(char_count_sorted, width=1)
12. methods
- enumerate:对于dict,返回index和key。没有value
- items只针对dict。返回 key,value的tuple list
- dict相对与list好的一点,每个元素只出现一次。可用于计数。
- 匿名函数 在items的key中,是定于针对每一个成员的。另外parameter expression。和列表推导式相反。