python 字典和对象

python字典

字典初始化的N种方法

  • 直接赋值

    1
    a = {"one": 1, "two": 2, "three": 3}
  • 先新建字典对象,再动态赋值

    1
    2
    3
    4
    b = dict()
    b["one"] = 1
    b["two"] = 2
    b["three"] = 3
  • 新建字典对象时,通过参数赋值

    1
    c = dict(one=1, two=2, three=3)
  • 新建字典对象时,通过嵌套的元组和列表来赋值

    1
    d = dict([("one", 1), ("two", 2), ("three", 3)])
  • 通过zip函数

    1
    2
    3
    4
    5
    e = dict(zip(["one", "two", "three"], [1, 2, 3]))

    list(zip(["one", "two", "three"], [1, 2, 3]))
    <<< [("one", 1), ("two", 2), ("three", 3)]
    zip()函数:将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表

    在 Python 3.x 中为了减少内存,zip() 返回的是一个对象。如需展示列表,需手动 list() 转换。

  • 新建字典对象使,直接传入字典对象作为参数

    1
    f = dict({"one": 1, "two": 2, "three": 3})
  • 利用fromkeys()为字典中所有的键赋相同的值

    1
    2
    3
    4
    5
    6
    g = dict.fromkeys(["height", "weight"], "normal")
    or
    g = dict.fromkeys(("height", "weight"), "normal")

    print(g)
    <<< {'height': 'normal', 'weight': 'normal'}

    若不指定第二个参数,所有的键对应的值为None

优雅的获取键值

1
2
3
4
5
6
7
8
9
10
11
12
13
# 字典可以这样获取到键的值
info= {'a': 1, 'b': 2}
info['a']
<<< 1
# 以上方式如果获取不存在的键的值就会触发一个KeyError异常
# 字典有一个get方法,使用它可以更优雅的获取字典相应键的值
info= {'a': 1, 'b': 2}
info.get('a')
<<< 1
info.get('c')
<<< None
info.get('c', 3)
<<< 3

字典的更新

1
2
3
4
5
6
# update方法
dict_a = {'a': 1, 'b': 2}
dict_b = {'a': 5, 'c': 7}
dict_a.update(dict_b)
print(dict_a)
<<< {'a': 5, 'b': 2, 'c': 7}

删除字典键值

1
2
3
4
5
6
7
8
9
10
11
12
# del内置关键字
dict_a = {'a': 1, 'b': 2}
del dict_a['a']
print(dict_a)
<<< {'b': 2}

# 字典的pop方法
dict_a = {'a': 1, 'b': 2}
dict_a.pop('a')
<<< 1
print(dict_a)
<<< {'b': 2}

获取全部的key和value

1
2
3
4
5
6
7
8
9
10
dict_a = {'a': 1, 'b': 2, 'c': 3}
# 获取所有keys
dict_a.keys()
<<< dict_keys(['a', 'b', 'c'])
# 获取所有的value
dict_a.values()
<<< dict_values([1, 2, 3])
# 获取所有的键值对
dict_a.items()
<<< dict_items([('a', 1), ('b', 2), ('c', 3)])

注:以上方法返回不是真正的列表,无法直接进行索引取值,可以利用for循环进行取值,或者在外层加一个list()将其转换成真正的列表,也就是list(dict_a.keys())。

本来我以为以上方法返回的是迭代器,但是尝试过使用next()方法,证明了并不是迭代器,正好简单说下迭代器和生成器。

1
2
next(dict_a.keys())
TypeError: 'dict_keys' object is not an iterator
  • 生成器【generator】(一边循环,一边计算,未知序列长度,惰性)

    如果一个函数种包含yield关键字,那么它就是一个生成器。在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回yield的语句处继续执行。

  • 可迭代对象【Iterable】

    可以用for循环,但无法用next(),例如list,tuple,dict,set,str。

  • 迭代器【Iterator】

    可以用for和next(),例如生成器;使用iter(),可以将Iterable变为Iterator。

面向对象

__slots__

1
2
3
4
5
6
7
8
9
10
# __slots__属性来限定对象的属性,不允许私自修改种类和个数
class Test(object):
__slots__ = ['a', 'b', 'c'] # or ('a', 'b', 'c')

t = Test()
t.d = 4
AttributeError: 'Test' object has no attribute 'd'
print(t.a)
AttributeError: b
# 也就是说,__slots__只是限定了对象的属性,但是还没有真正意义上给对象确定添加这些属性。

__init__()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 类有一个名为 __init__() 的特殊方法(构造方法),该方法在类实例化时会自动调用
class Test(object):
__slots__ = ['a', 'b', 'c']

def __init__(self):
self.a = '1'

t = Test()
print(t.a)
<<< 1
# 当然, __init__() 方法可以有参数,参数通过 __init__() 传递到类的实例化操作上
class Test(object):
__slots__ = ['a', 'b', 'c']

def __init__(self, a, b):
self.a = a
self.b = b

t = Test(100, 200)
print(t.a)
<<< 100

注:self代表类的实例,而非类

“_”和”__”的含义

以”_”开头的变量或者方法是protected的,只能允许其本身与子类进行访问;

以”__”开头的变量或方法是私有的,只能允许这个类本身进行访问;

注:__xx__是特殊变量或者特殊方法,非私有变量

hasattr()、getattr()、setattr()

  • hasattr(obj, target)
  • getattr(obj, target, default)
  • setattr(obj, target, default)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Test1(object):

__slots__ = ('a', 'b', 'c')

# 将该类的属性全部显示定义并赋初值(初值1)
test = Test1()
for key in test.__slots__:
setattr(test, key, 1)

# 检查对象是否含有目标属性
print(hasattr(test, 'a'))
<<< True
print(hasattr(test, 'd'))
<<< False

# 获取目标属性值
print(getattr(test, 'b'))
<<< 1
print(getattr(test, 'd'))
AttributeError: 'Test1' object has no attribute 'd'
# 可以看出,getattr方法,获取的属性不存在会报错,通过设置默认值可以解决
print(getattr(test, 'd', 1))
<<< 1

对象转换成字典

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Test1(object):    

__slots__ = ('a', 'b', 'c')

test = Test1()
test.a = 1
test.b = 2

# 将对象test转换成字典
result = dict()
for key in test.__slots__:
# 此处必须设置默认值,不然极有可能会报错,例如此例中没有对属性c进行显示定义
result[key] = getattr(test, key, '')
print(result)
<<< {'a': 1, 'b': 1, 'c': ''}

python中的三目运算

在C/C++/C#或者Java中,都有三目运算符,即条件表达式1?表达式1:表达式2;

意为如果条件表达式1值为真,则这个整个表达式的取值为表达式1的值,否则为表达式2的值。

python没有a?b:c的形式,但是有类似的表达式,a if b else c,意为若b为真,返回a,否则返回c。

1
2
3
4
5
6
7
8
a = 10
b = 20
c = a if True else b
d = a if False else b
print(c)
print(d)
<<< 10
<<< 20