python数据类型(二)

继续python数据类型。

字典 dict

dict是dictionary的缩写,其存储数据以key:value方式,类似java中的map,javascripts中的jason。字典可以存储任意对象,也可以是不同的数据类型。
字典的创建是每个key-value之间使用:(冒号)分隔,每个key:value对之间使用,(逗号)分隔,整个字典使用{}(大括号)括起来,格式为d = {key1: value1, key2: value2 }。字典中的key不能相同,value可以相同。字典中的key必须是不可变的,数字、字符串、元组都可以作为key,但是列表不可以作为key。

字典定义

1
2
3
4
5
>>> d1 = dict(name = "xiaohh", age = 18)
>>> d2 = {"name": "xiahh", "age": 18 }
>>> d3 = dict([("name","xiaohh"),("age",18)])
>>> print(d3)
{'name': 'xiaohh', 'age': 18}

访问字典中的值,直接将对应的key放入[]即可。

1
2
3
>>> d1 = {"name": "xiahh", "age": 18 }
>>> d1["name"]
'xiahh'

当访问的key不存在时将会报错。

1
2
3
4
5
>>> d1 = {"name": "xiahh", "age": 18 }
>>> d1["address"]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'address'

修改字典
既可以新增key:value键值对,也可以修改已有的内容。
新增键值对

1
2
3
4
>>> d1 = {"name": "xiahh", "age": 18 }
>>> d1["address"] = "beijing"
>>> print(d1)
{'name': 'xiahh', 'age': 18, 'address': 'beijing'}

修改已有内容

1
2
3
4
>>> d1 = {"name": "xiahh", "age": 18 }
>>> d1["age"] = 3
>>> print(d1)
{'name': 'xiahh', 'age': 3}

当对同一值进行多次修改时,前面的值将被覆盖。
删除字典
可以对字典的键值进行删除,也可以直接删除字典。
删除键值

1
2
3
4
>>> d1 = {"name": "xiahh", "age": 18 }
>>> del d1["age"]
>>> print(d1)
{'name': 'xiahh'}

删除字典

1
2
3
4
5
6
>>> d1 = {"name": "xiahh", "age": 18 }
>>> del d1
>>> print(d1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'd1' is not defined

下面介绍字典常用方法

get()

返回指定键的值,若值在字典中不存在则返回默认值(默认值为None,可自定义)。

1
2
3
4
5
6
7
>>> d1 = {"name": "xiahh", "age": 18 }
>>> print(d1.get("name"))
xiahh
>>> print(d1.get("address")) #不存在则返回默认值None
None
>>> print(d1.get("address",-1)) #此处-1为自定义的默认值,当不存在时则返回-1
-1

setdefault()

若查找的键在字典中则返回对应值,若不存在则插入对应的键及默认值(默认值为None,可自定义)。

1
2
3
4
5
6
7
8
9
>>> d1 = {"name": "xiahh", "age": 18 }
>>> d1.setdefault("name")
'xiahh'
>>> d1.setdefault("address")
>>> print(d1)
{'name': 'xiahh', 'age': 18, 'address': None}
>>> d1.setdefault("num",168)
>>> print(d1)
{'name': 'xiahh', 'age': 18, 'address': None, 'num': 168}

keys()

以列表形式返回字典中所有键。

1
2
3
>>> d1 = {"name": "xiahh", "age": 18 }
>>> d1.keys()
dict_keys(['name', 'age'])

values()

以列表形式返回字典中所有值。

1
2
3
>>> d1 = {"name": "xiahh", "age": 18 }
>>> d1.values()
dict_values(['xiahh', 18])

items()

以列表的形式返回可遍历的元组数据。

1
2
3
4
5
6
7
>>> d1 = {"name": "xiahh", "age": 18 }
>>> d1.items()
dict_items([('name', 'xiahh'), ('age', 18)])
>>> for i,j in d1.items(): print(i,j)
...
name xiahh
age 18

说明:在python2中存在items()iteritems()2种方法,items()返回一个字典的拷贝列表,占用额外内存;iteritems()返回字典列表操作后的迭代,不占用额外内存。在python3中使用items()方法替代iteritems()方法,可以采用for进行循环遍历。

update()

将参数中的字典更新至原字典中。无返回值。

1
2
3
4
>>> d1 = {"name": "xiahh", "age": 18 }
>>> d1.update({"address": "beijing"})
>>> print(d1)
{'name': 'xiahh', 'age': 18, 'address': 'beijing'}

pop()

删除字典中指定键对应的值,返回值为被删除的值。其中键必须给出,若指定的键不存在则返回默认值。

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> d1 = {"name": "xiahh", "age": 18 }
>>> d1.pop("name") #给出的键存在则返回被删除的值
'xiahh'
>>> print(d1)
{'age': 18}
>>> d1.pop("address") #给出的键不存在且不指定默认值,报错
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'address'
>>> d1.pop("address",-1) #给出的键不存在,指定默认值,返回默认值
-1
>>> print(d1)
{'age': 18}

clear()

清空字典。无返回值。

1
2
3
4
>>> d1 = {"name": "xiahh", "age": 18 }
>>> d1.clear()
>>> print(d1)
{}

copy()

返回字典的一个浅拷贝。使用=进行的直接赋值和copy()进行的浅拷贝不一样,赋值只是对原对象的引用;浅拷贝则是对父对象进行拷贝,对象的子对象则是引用。

1
2
3
4
5
6
7
8
9
10
11
>>> d1 = {"name": "xiahh", "age": 18, "num": [1,2,3] }
>>> d2 = d1 #d2是赋值
>>> d3 = d1.copy() #d3是浅拷贝,其中num对应的值为元组,对于字典属于子对象
>>> d1["name"]="superman"
>>> d1["num"].remove(1)
>>> print(d1)
{'name': 'superman', 'age': 18, 'num': [2, 3]}
>>> print(d2)
{'name': 'superman', 'age': 18, 'num': [2, 3]}
>>> print(d3)
{'name': 'xiahh', 'age': 18, 'num': [2, 3]}

zip()

将两个列表组成字典。

1
2
3
4
5
>>> list1 = ("name","age")
>>> list2 = ("xiaohh","18")
>>> d1 = dict(zip(list1, list2))
>>> print(d1)
{'name': 'xiaohh', 'age': '18'}

sorted()

对字典进行排序,按照键或值。

1
2
3
4
5
>>> d1 = {"name": "xiahh", "age": "18" }
>>> print(sorted(d1.items(),key=lambda d: d[1])) #按照值进行排序
[('age', '18'), ('name', 'xiahh')]
>>> print(sorted(d1.items(),key=lambda d: d[0])) #按照键进行排序
[('age', '18'), ('name', 'xiahh')]

需要注意,排序只能针对同一类型,字符串或者数字,不能用于不同类型值。
当字典定义为d1 = {"name": "xiahh", "age": 18 },只能使用键进行排序,不能使用值进行排序,否则报错。
TypeError: '<' not supported between instances of 'int' and 'str'

注意:dict内部存放顺序和key放入的顺序没有关系。
list相比,dict有一下几个特点:

  • 查找和插入速度极快,不会随着key的增加而变慢。
  • 需要占用大量内存,内存浪费多。

list则相反:

  • 查找和插入的时间随着元素的增加而增加。
  • 占用空间小,浪费内存很少。

所以dict是用空间来换取时间的一种方法。
dict可以用在需要告诉查找的很多地方,特别注意dict的key必须是不可变对象。这是因为dict根据key来计算value的存储位置,如果每次计算相同的key得到的结果不同,那么dict内部就完全混乱了。这种通过key计算位置的算法称为哈希算法(Hash)。
在python中,字符串、整数等都是不可变的,可以作为dict的key。list的可变的,不可以作为dict的key。

集合set

set是一个无序不重复元素的序列。基本功能是进行成员关系测试和删除重复元素。
可以使用大括号{}或者set()函数创建集合,但是:创建一个空的集合必须使用set()而不是{}{}是用来创建一个空字典的。

创建set

创建set需要提供一个list作为输入集合

1
2
3
>>> s = set([1, 2, 3])
>>> s
{1, 2, 3}

传入的参数[1, 2, 3]是一个list,显示的{1, 2, 3}说明这个set内部有这3个元素,显示的顺序并不表示set是有序的。

去重

重复元素在set中会自动被过滤。

1
2
3
>>> s = set([1, 1, 2, 2, 3, 3, 4, 5])
>>> s
{1, 2, 3, 4, 5}

添加元素

通过add(key)方法可以添加元素到set中,可以重复添加,但无效果。

1
2
3
4
5
6
7
8
9
>>> s = set([1, 2, 3])
>>> s
{1, 2, 3}
>>> s.add(4)
>>> s
{1, 2, 3, 4}
>>> s.add(4)
>>> s
{1, 2, 3, 4}

删除元素

通过remove(key)方法可以删除元素。

1
2
3
4
5
>>> s
{1, 2, 3, 4}
>>> s.remove(4)
>>> s
{1, 2, 3}

集合操作

set可以看做数学意义上的无序和无重复元素的集合,因此两个set可以进行数学意义上的交集、并集等操作。

1
2
3
4
5
6
7
8
9
10
>>> s1 = set([1, 2, 3])
>>> s2 = set([2, 3, 4])
>>> s1 & s2
{2, 3}
>>> s1 | s2
{1, 2, 3, 4}
>>> s1 - s2
{1}
>>> s1 ^ s2
{1, 4}

set和dict唯一的区别在于没有存储对应的value,但是set原理和dict一样,同样不可放入可变对象。因为无法判断两个可变对象是否相等,也就无法判断set内部不会有重复元素。

其他通用方法

help()

用于查看帮助信息

1
2
>>> d1 = {"name": "xiahh", "age": 18 }
>>> help(d1)

可以查看到字典的定义及内置方法等信息。
python-help-dict

强制类型转换

int()
str()
list()
tuple()
dict()

len()

返回对象的长度。

1
2
3
4
5
>>> len(str)
15
>>> d1 = {"name": "xiahh", "age": 18 } #字典返回键的个数
>>> len(d1)
2

type()

返回对象类型。

1
2
3
4
5
6
>>> str = "I'm a superman!"
>>> type(str)
<class 'str'>
>>> d1 = {"name": "xiahh", "age": 18 }
>>> type(d1)
<class 'dict'>

isinstance()

判断一个对象是否是已知的类型。如果是返回True,否则返回False。

1
2
3
4
5
6
>>> d1 = {"name": "xiahh", "age": 18 }
>>> isinstance(d1,dict) #第二个参数可以是一种数据类型
True
>>> a = 123
>>> isinstance(a, (int, str, dict)) #第二个参数是数据类型组成的元组
True

注意:

  • type() 不会认为子类是一种父类类型
  • isinstance() 认为子类是父类类型
1
2
3
4
5
6
7
8
9
10
11
class A:
pass

class B(A):
pass


print(isinstance(A(), A)) # returns True
print(type(A()) == A) # returns True
print(isinstance(B(), A)) # returns True
print(type(B()) == A) # returns False

enumerate()

将一个可遍历的数据对象(如列表、元组或字符串)组合成一个索引序列,同时列出数据和数据下标。

1
2
3
>>> t1 = ["春", "夏", "秋", "冬"]
>>> list(enumerate(t1))
[(0, '春'), (1, '夏'), (2, '秋'), (3, '冬')]

常用在for循环中

1
2
3
4
5
6
7
8
>>> t1 = ["春", "夏", "秋", "冬"]
>>> for index, item in enumerate(t1):
... print(index, item)
...
0
1
2
3

不可变对象

python基础数据类型共有6种,其中不可变数据类型有4个,可变数据类型2个。

  • 不可变:数字、字符串(str)、元组(tuple)、集合(set)。
  • 可变:列表(list)、字典(dict)。
    可变对象,例如list,当对list进行操作时,list内部的内容是会变化的。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    >>> list1 = ['c', 'b', 'a']
    >>> list1.sort()
    >>> list1
    ['a', 'b', 'c']
    ```
    不可变对象,调用自身的任意方法,也不会改变该对象自身的内容。相反,这些方法会创建新的对象并返回,这样就保证了不可变对象本身不变。
    ``` python
    >>> str1 = 'abc'
    >>> str2 = str1.replace('a', 'A')
    >>> str1
    'abc'
    >>> str2
    'Abc'

Recommended Posts