python之数据结构

对于一门语言来说,数据结构是其所有精华的所在,是python开发的基础。对于很多新人来说,就是觉得挺简单的,实际上手还是较困难。

python这里介绍四种数据结构:
1.元组
2.列表
3.字典
4.序列

元组

tuple是由一系列元素组成的ds,所有元素被包含在一对圆括号中。创建元组时,可以不指定元素个数,但是一旦创建之后,就不能进行任何修改。
这里需要注意一下,如果创建的元组只包含一个元素,通常会忽略单元素后的逗号。正确写法如下:

tuple = (apple,)
print (tuple[0])
print (type(tuple))

这段代码定义了一个单元素的tuple“apple”,并且类型为

元组,列表,字典等都是从0开始的,[0]获取的就是第一个元素。

元组创建之后,不能进行修改,也不能进行赋值操作。

元组可以进行负数索引,分片索引,另外元组还可以由其他元组组成,就成了二元元组。

元组的遍历
这里介绍下二元元组的遍历。

for i in tuple:
    for j in i:
        print(j)

##列表

列表是方括号。

列表可以实现添加 删除 查找等操作,元素的值可以被修改。

添加使用append()
还可以考虑insert(),不过insert要指明位置。
删除直接用remove()
pop()是取出最后一个元素。
列表的使用和元组十分相似,支持负数索引 分片还有多元列表等特性,但是列表中的元素可以进行修改。

列表还可以进行连接操作。一种是extend()连接两个不同的列表,另外一种是使用运算符“+”或“+=”。

list = ["apple","banana","orange","grape"]  
print(list.index("grape"))  
print("orange" in list)

打印索引,
判断orange是否在列表中。

列表排序和反转

list.sort()
list.reverse()  

sort()这个函数,需要仔细说明下,sort(cmp,key=None,reverse=False)

在这和大家分享一下机器学习里的一个案例,看看列表的操作。

统计 Python 中的字数
问题
在 Python 中实施函数“count_words()”,该函数将字符串“s”和数字“n”用作输入,并返回“s”中“n”个出现频率最高的单词。返回值应该是一个元组列表 - 出现频率最高的“n”个单词及其相应的出现次数“[(, ), (, ), …]”,按出现次数的降序排列。
您可以假设所有输入都是小写形式,并且不含标点符号或其他字符(只包含字母和单个分隔空格)。如果出现次数相同,则按字母顺序排列出现次数相同的单词。
例如:

print count_words("betty bought a bit of butter but the butter was bitter",3)

Output:

[('butter', 2), ('a', 1), ('betty', 1)]
  """Count words."""
from collections import Counter
from operator import itemgetter
def count_words(s, n):
    """Return the n most frequently occuring words in s."""
    cnt = Counter()
    for word in s.split(" "):
        cnt[word] += 1
    a = cnt.items()
    b = sorted(a,key=lambda a:a[0],reverse=False)
    c = sorted(b,key=itemgetter(1),reverse=True)
    top_n = c[0:n]
    # TODO: Count the number of occurences of each word in s

    # TODO: Sort the occurences in descending order (alphabetically in case of ties)

    # TODO: Return the top n words as a list of tuples (<word>, <count>)
    return top_n


def test_run():
    """Test count_words() with some inputs."""
    print count_words("cat bat mat cat bat cat", 3)
    print count_words("betty bought a bit of butter but the butter was bitter", 3)


if __name__ == '__main__':
    test_run()

如何来分析这个案例呢?

首先是定义一个字符串

s=“betty bought a bit of butter but the butter was bitter”

接着使用文档中提到的collections来处理这个统计

from collections import Counter
cnt = Counter()
for word in s.split(" "):
    cnt[word] += 1

这里处理完之后,需要停下来检查一下cnt是啥类型
class ‘collections.Counter’

Counter({'butter': 2, 'a': 1, 'bitter': 1, 'of': 1, 'but': 1, 'betty': 1, 'bit': 1, 'was': 1, 'the': 1, 'bought': 1})

这个形式应该就是我们后续要介绍的dict字典类型,我们需要把它转换为列表

cnt.items()

转换了之后,我们还需要做哪些处理呢?

[('a', 1), ('butter', 2), ('bitter', 1), ('of', 1), ('but', 1), ('betty', 1), ('bit', 1), ('was', 1), ('the', 1), ('bought', 1)]   

看看题目的要求,统计次数多的在前,一是数值大的要靠前站;
另外就是数值一样,按照字典顺序,a-z这种排列一下。

这里我就考虑使用这种顺序尝试一下咯。

先根据字典顺序,排列一下

sorted(a,key=lambda a:a[0],reverse=False)

这个是正常的升序排列,得到结果:

[('a', 1), ('betty', 1), ('bit', 1), ('bitter', 1), ('bought', 1), ('but', 1), ('butter', 2), ('of', 1), ('the', 1), ('was', 1)]

接下来就是把数值大的调到前面去,也就是比较一下第二个值,按照降序排列处理一下

from operator import itemgetter
sorted(b,key=itemgetter(1),reverse=True)

这样就基本实现了对列表里的排序,接着分片处理下就达到了题目要求。

这个方案是我的初步方案,可能不是最简便的,供大家参考下,嘻嘻。

列表还有一个操作就是实现堆栈和队列,这个在大学的数据结构课程有简单接触的,问题就是很多只知道大概了啊。。

堆栈就是后进先出

队列则是先进先出
使用列表的append()和pop()操作可以模拟这两个数据结构
append()可以把一个元素添加到堆栈的顶部,
pop()把堆栈的最后一个元素弹出来。

队列的不同之处在于弹出时参数设置不一样,
pop(-1)弹出第一个元素

##字典

字典也是较为常见的,也是比较的重要的数据结构。key-value这种键值对,也是数据库的一种基本模式。

字典是花括号{}

这里需要注意一下,键是区分大小写的。一般而言,创建字典时,可以使用数字作为索引。
键值对这种结构,

value=dict[key]

说下字典的遍历:

for (k,v) in  dict.items():
    print ("dict[%s] ="% k,v)

值也可以是字典 元组 或者是字典,这种称为混合型字典。
字典有这么些方法:

keys() 返回keys列表
value()返回value列表
get()
get()访问字典中的value值减少了代码的长度,而且表达方式容易理解,避免了使用if语句带来的维护代价。
update()
update()函数相当于一个合并函数,把一个字典的key和value值全部复制到另外一个字典中。
D.update(E) -> None

把字典E的内容合并到字典D中,有相同的键值,e的值会覆盖d的。
setdefault()
可以创建新的元素并设置默认值,声明如下:

D.setdefault(k,[d]) -> D.get(k,[d])

还有一些常用方法:
items() 返回(key,value)元组组成的列表
iteritems() 返回指向字典的遍历器

字典还有排序和复制

排序的话和列表的差不多

print (sorted(dict.items(), key=lambda d:d[0]))

这是按照key排序

前面提到的update函数,比如把a字典的内容复制到b字典,并且b字典原有的顺序保持不变,从而实现字典b的扩展。但是,如果需要把a的内容复制到b,并且清除b中的原有内容的话,则需要使用copy()。

copy()是浅拷贝
还有deepcopy()是深拷贝

深拷贝能够拷贝对象内部所有的数据和引用,很像c语言中的指针。
字典b浅拷贝a的数据,如何b的数据发生添加 删除或者修改,a中的数据也将发生变化。
如果是深拷贝,a的数据是不会受到b的变化而变化的。

深拷贝和浅拷贝适用于python的任何对象,不只是局限于字典。

另外,还有全局字典 sys.modules模块,这个字典是python启动时就加载在内存当中的,这个起到缓存的作用。

##序列

序列是具有索引和切片能力的集合,元组 列表 字符串都属于序列。

这里主要是元组和列表的区别。

元组是只读的,而且元组没有提供排序和查找的方法。
列表可读写,而且提供丰富的操作,支持排序 查找。
元组的数据通常具有不同的含义,而列表的数据通常具有相同的含义。
相同之处则是都支持负数索引和分片的操作。

每天能适当做一些自己的总结,对于知识的掌握还是很有好处的。
希望自己能够好好坚持。
有目标的人咋个说呢?
今天看到一个前辈说,真正的牛人也许一辈子只投4次简历。
你就错过了毕业就去好公司的机会,所以需要更加努力学习。
对于初级的程序员来说,很想做出一点东西来,但是又不知道哪些重要哪些不重要,到底该学到什么程度,不知道导致不确定,不确定导致决策瘫痪,干脆就啥也不动,整年整年苦闷的像没头苍蝇一样到处乱撞,荒废时间。

今年不论在哪里工作,决定給自己设定一个目标,在博客上写下52篇博客,虽然前期可能借鉴他人的经验较多,但是希望自己还是能保持到平均一周一篇的水平,不断写写写去积累。

周博客这里可能局限于一些技术见闻,所见所感这块,另外希望自己能写下10篇左右的读书笔记。


没有什么面试比持续两年的面试更具有信息量,书单加上github。