Python元组&字典

元组:

  • 用于存储数据,行为不能被存储在元组中。

  • 不可变的,即不能对其添加、删除或替换对象。

  • 主要好处就是它的不可变性,可以把它作为字典的键,或者用在一个对象需要散列值的地方。

  • 以下两种写法都可以创建元组,推荐加括号。当把元组集成到其他对象中,如函数调用、列表解析、生成器,括号是必须的,否则解释器不能识别这是一个元组还是另一个参数。

t1 = "A", 1, 2, 3
t2 = ("B", 4, 5, 6)
  • 元组拆分:在拆分时,元组必须拆分为与其长度相等的变量,否则解释器回抛出异常。
    symbol, num1, num2, num3 = t1

  • 还可以用分片符提取元组中的数据:
    t1[1, 3] #得(1, 2)

元组的主要缺点就是数据的可读性差,当我们没有给数据分配名字时,即没有像symbol, num1, num2, num3 = t1这种代码时,我们不会知道t1元组里的第一个值代表symbol,第二个值代表num1…我们访问元组时也只能是类似t1[1]这样,不能知道数据的具体指代。
->解决方案:命名元组

命名元组:

from collections import namedtuple
T = namedtuple("T", "symbol num1 num2 num3")
#step1:使用collections.namedtuple来创建一个类
t3 = T("C", 7, 8, 9)    
#step2:创建该类的实例
  • 命名元组像普通元组那样可以打包或拆分,还可以像访问类属性一样访问其中某个属性,如图:
    这里写图片描述

如果我们需要改变存储的数据,那么就需要用到字典了。

字典:

  • 被存储的对象称为,被用作索引的对象成为

  • 键可以是字符串、整数、浮点数甚至元组,但不能是列表和字典(原因见注2)。值则没有限制,可以是列表和字典。

  • 可以用dict()构造函数或{}快捷语法来构造字典,在实践中一般用{}。例如,在股票应用中,我们需要通过股票代码查找股价,可以创建一个一股票代码为键,包含现价、最高价、最低价的元组为值的字典:

stocks = {"GOOG": (613.30, 625.86, 610.50), 
          "MSFT": (30.25, 30.70, 30.19)}
  • 常用方法:

    • get方法:接收一个键作为第一个参数,第二个参数可选,当键不存在时输出第二个参数中的语句(如没有第二个参数则需要用print,输出结果为None),存在时输出对应的值。
      这里写图片描述
      这里写图片描述

    • setdefault方法:如果该键在字典中,行为同get方法,如果键不在字典中,它不仅会返回我们在调用方法时给出的默认值(同get),还会将该键设置为相同的值。
      这里写图片描述

    • keys(),values():返回一个包含所有键或所有值的迭代器,可以像列表一样使用它们,或是通过for循环来遍历它们。

    • items()方法:返回一个对字典中每个项目形成一个如(键,值)对这样的元组的迭代器。这个迭代器结合元组拆分,可以在for循环中使遍历键和值事半功倍。
      这里写图片描述

注1:字典打印时并不会按照数据插入字典的顺序打印出来。为了使键查找足够快,字典使用了哈希算法,因此字典在内部是无序的。
注2:列表可能在任何时候发生变化(如添加或删除列表中元素),所以列表不能被哈希称一个特定的值,所以列表不能用作键。出于同样原因,字典也不能用作另一字典的键。

defaultdict:

  • defaultdict类在它的构造函数中可以接收一个函数作为参数,当访问字典中一个不存在的键时,它就会以不含参数的形式调用该函数,创建一个默认值。

  • 一个例子:统计一个字母在给定句子中出现的次数。

#使用setdefault
def letter_frequency(sentence):
    frequencies = {}
    for letter in sentence:
        frequency = frequencies.setdefault(letter, 0)
        frequencies[letter] = frequency + 1
    return frequencies
#使用defaultdict
from collections import defaultdict

def letter_frequency(sentence):
    frequencies = defaultdict(int)
    for letter in sentence:
        frequencies[letter] += 1
    return frequencies

在这个例子中,所调用的函数是int,也就是一个整数对象的构造函数。通常情况下,在代码中创建一个整数只需要键入一个整数数字。而如果使用int构造函数来创建一个整数,我们可以将想要创建的项目传给它(如将一连串的数字字符转换成一个整数)。但如果我们调用int时不带任何参数,它就会简单地返回0。
在这段代码中,如果字母在defaultdict中不存在,则在我们访问它时会返回0,之后我们为这个数字加1来表示我们发现了该字母的一个实例,当我们下次再找到一个时,就再增加其值。

  • 又一个例子:创建一个defaultdict,其中每个元素都包含一个元组,记录当时插入字典中的项目数量和一个用来存储其他数据的空列表。
from collections import defaultdict

num_items = 0

def tuple_counter():
    global num_items
    num_items += 1
    return (num_items, [])

当我们运行这段代码时,可以再同一行代码中同时做到访问空键并插入列表两个动作:

这里写图片描述

注:这个例子虽然简洁地展示了如何用自己的函数创建defaultdict,但实际上这并不是很好的代码。全局变量的使用意味着如果我们创建了4个不同点defaultdict代码段,每个都使用一个tuple_counter,那么它将计算再所有字典中全部条目的数量,而不是为每一个字典记录不同的数。最好的办法是创建一个类,并将这个类中的一个方法传给defaultdict。

参考资料:《Python 3 面向对象编程》 Dusty Phillips著

猜你喜欢

转载自blog.csdn.net/wying_0/article/details/78299678