从C到Python(二)

Python与C中的一些数据结构的异同

Python中有四种内置的数据结构——列表(List)、元组(Tuple)、字典(Dictionary)和集 合(Set)。
C语言中常见的数据结构如下:数组(Array)结构体(Struct)队列(Queue)链表(Linked List)树(Tree)图(Graph)
以下对比来看两者之间的区别
Python
序列是Python中最基本的数据结构。序列中的每个元素都分配一个数字,和大多数程序语言一样,从0开始,以此类推。Python有6个序列的内置类型,但最常见的是列表、元组和字符串。
列表 是一种用于保存一系列有序项目的集合,这些项目(元素)可以是不同的数据类型。就像是一个点菜的单子,你可以要汤,炒菜,甜品,还有酒水饮料等不同类的东西。
创建一个列表,将元素用方括号括起来,中间用逗号隔开即可。如下所示:

menu1 = ['紫菜蛋花汤', '水煮肉片', "82年sprite", 2000]

元组 与列表类似,元组创建使用小括号,列表使用方括号。不同之处在于元组的元素不能修改。就好比已经上桌的菜你不能再退回去。元组中只包含一个元素时,需要在元素后面添加逗号,否则括号会被当作运算符使用:

menu2= ('紫菜蛋花汤', '水煮肉片', "82年sprite", 2000)
menu3= ('紫菜蛋花汤',)

序列都可以进行的操作包括索引,切片,加,乘,检查成员。
索引 访问列表和元组中的指定位置的元素,
切片 截取索引中的一段元素。
加 + 号用于连接序列
乘 * 号用于重复序列

print ("menu1 [0]: ", menu1 [0])    #索引演示  打印列表第一个元素
print ("menu2 (0:3): ",menu2[0:3])  #切片演示  打印元组从第一个到第四个元素
print  (menu2+menu3)                #加法演示 拼接两个元组
print(menu3*3)                      #乘法演示  重复列表三次
if  2000 in menu1:                  #检查成员演示
print("账单费用为2000")              #同in运算符之前用法一致

-输出
- menu1 [0]: 紫菜蛋花汤
- menu2 (0:3): (‘紫菜蛋花汤’, ‘水煮肉片’, ‘82年sprite’)
(‘紫菜蛋花汤’, ‘水煮肉片’, ‘82年sprite’, 2000, ‘紫菜蛋花汤’)
(‘紫菜蛋花汤’, ‘紫菜蛋花汤’,
‘紫菜蛋花汤’)
账单费用为2000

由于列表里的元素可变,不仅可以做元组可以做的事,在使用上还有更多的灵活性。以下演示列表的可变性

menu1[0]='银耳莲子羹'        #通过索引对列表元素进行赋值
print(menu1)            
menu1[1:3]=["麻婆豆腐"]     #通过切片对列表元素进行赋值,
print(menu1)                #用麻婆豆腐替换掉原来的水煮肉片和82年spirit,列表长度缩短1个单位。
del menu1[2]                #删除一个元素
print(menu1)    
del menu1[:2]           #删除一个切片
print(menu1)    

结果如下,确实改变了原始的列表

  • [‘银耳莲子羹’, ‘水煮肉片’, ‘82年sprite’, 2000]
  • [‘银耳莲子羹’, ‘麻婆豆腐’, 2000]
    []

关于列表和元组,基本内容就这些,当然两个还有其对应的函数(方法),用法简单,不再介绍。虽然列表比元组有好多好处,但元组也有其用武之地

  1. 元组比列表快,由于元组不可变,所以计算机在存储时会用一种比列表更快的方式,如果程序中有大量的信息来处理,速度上会有明显的差异。

  2. 元组的不可变性时创建常量的好方法,使用元组可以为代码提供一层安全保护。

  3. 有时候一定要用元组,在某些情况下,Python需要不可变的值,比如字典

字典 字典将信息成对存储,像现实中的字典,每个条目是一对:一个单词和它的说明。当查询单词时,得到一个说明。Python中,我们将键值(Keys)(即单词)与值(Values)(即单词词意)联立到一起。在这里要注意到键值必须是唯一的,正如在现实中的字典一样,一部字典中一个单词只会解释一次。

创建字典 先输入一个键,然后一个冒号,然后是这个键的值,构成一个键值对。各个键值对之间用逗号隔开,再用花括弧把所有的键值对包起来就构成了字典。格式如下

dictionary = {“key1”:”value1”, “key2”:”value2”, “key3”:”value3”, “key4”:”value4”}
键必须是唯一的,但值则不必。值可以取任何数据类型,但键必须是不可变的,如字符串,数字或元组。像实际字典一样,可以通过键获取值,但不能通过值获取键,对不存在的键进行读取删除都会引发错误,包括因此在获取值之前最好先用in运算符对键进行测试,但是,in只能判断键是否存在,不能判断值是否存在。除了用键来获取值之外,还可以用字典方法get()来获取,该方法有一个内建的安全机制来处理键不存在的情况,如果键不存在,会返回一个默认值,这个默认值是自己定义的,如果不提供默认值的话返回None。

添加键值对 字典是可变的,因此可以进行修改。格式 dictionary [new_key] = definition
替换键值对 把原来的键的值做新的解释,写法和添加键值对一样 dictionary [old_key] = re definition
删除键值对 把字典中的键删掉就可以删掉整个键值对。格式 del dictionary [key]
以下演示字典的具体用法

dictionary = {404:"meaning page not found",
        "GFW":"Great Firewall of China",
        "Python":"An object-oriented programming language"}
dictionary["VPN"] = "Virtual private network"       #添加一个键值对

if "Python" in dictionary:          #未经检查直接读取可能出错
    dictionary["Python"] = "The best programming language in the world"
    print("what is the Python?",dictionary["Python"])     #把相应的键放入方括弧即可访问
if "Python" in dictionary:
    del dictionary["Python"]        #删除Python项
print("what is the Python?",dictionary.get("Python","This term is not defined\n"))

print(dictionary)

结果如下
- what is the Python? The best programming language in the world what
is the Python? This term is not defined

{404: ‘meaning page not found’, ‘GFW’: ‘Great Firewall of China’,
‘VPN’: ‘Virtual private network’}

关于字典还有一些其他的方法,用到再说。

集合
集合(Set)是简单对象的无序集合(Collection)。当集合中的项目存在与否比起次序或其出 现次数更加重要时,我们就会使用集合。
通过使用集合,你可以测试某些对象的资格或情况,检查它们是否是其它集合的子集,找到 两个集合的交集,等等。(来自简明Python教程)
至于如何创建和使用集合,也是稍作改动,毕竟其他书上的介绍太少,以后再补充。

bri = set(['brazil',    'russia',   'india']) 
print('india'   in  bri  )
print('usa' in  bri  )

bric    =   bri.copy() 
bric.add('china') 
print(bric.issuperset(bri))

bri.remove('russia') 
print(bri   &   bric    )      #    OR  bri.intersection(bric)

输出结果为
- True
- False
- True
- {‘brazil’, ‘india’}

不难看出,集合就像是数学中的集合一样,可以进行交并补运算。

再说C语言中的数组(Array)结构体(struct)队列(Queue)链表(Linked List)
至于 树(Tree)图(Graph)堆(Heap)堆栈(Stack)散列表(Hash)等,限于知识储备有限,后面补上。

C 数组
数组,存储一个固定大小的相同类型元素的顺序集合。数组是用来存储一系列数据,但它往往被认为是一系列相同类型的变量。所有的数组都是由连续的内存位置组成。最低的地址对应第一个元素,最高的地址对应最后一个元素。因此,数组中的特定某个元素可以通过索引访问。

创建数组 元素类型 数组名 [元素个数]; type name[size];
int a[10] = {}; //声明了一个a的数组,里面有10个int类型的变量,默认变量值为0。

数组 创建的时候使用一条初始化语句
int a[10] = {1,2,3,4,5};/*大括号内部的元素个数小于声明的个数,缺少的值默认为0,若大于声明的个数,则报错*/
也可以逐个初个初始化
a[0] = 1;a[1]=2;a[3]=3;…//所有未被赋值的元素为0,对不存在的元素如a[11]赋值会包错。

以下演示数组的声明与使用

#include<stdio.h>
 int main()
{ 
    int i;
    int a[10]={};
    int b[10] = {1,2,3,4,5};
    printf("a[]的值为\t\t\t");    
    for (i=0;i<10;i++)
    {
        printf("%d\t",a[i]);    
    }
    printf("\nb[]的值为\t\t\t"); 
     for (i=0;i<10;i++)
    {
        printf("%d\t",b[i]);    
    }   
      for (i=0;i<5;i++)
    {
        a[i]=i;    
    }  
   printf("\n修改a[]之后的值为\t");    
    for (i=0;i<10;i++)
    {
        printf("%d\t",a[i]);    
    }
    return 0; 
}

结果为:
a[]的值为 0 0 0 0 0 0 0 0 0 0
b[]的值为 1 2 3 4 5 0 0 0 0 0
修改a[]之后的值为 0 1 2 3 4 0 0 0 0 0

二维数组
二维数组,实际上是一个一维数组的列表。声明一个 x 行 y 列的二维整型数组,形式如下:
type DoubleArray [ x ][ y ];

初始化二维数组
多维数组可以通过在括号内为每行指定值来进行初始化。下面是一个带有 3 行 3 列的数组。

int a[3][3] = {  
 {0, 1, 2}    /*  初始化索引号为 0 的行 */
 {3, 4, 5}    /*  初始化索引号为 1 的行 */
 {6, 7, 8}   /*  初始化索引号为 2 的行 */
};

内部嵌套的括号是可选的,下面的初始化与上面是等同的:
int a[3][3] = {0,1,2,3,4,5,6,7,8};

访问二维数组元素
二维数组中的元素是通过使用下标(即数组的行索引和列索引)来访问的
printf(“%d”,a[1][1]); //打印第二行第二个元素
二维数组存放字符串,读取时当一维数组使用。比如:

#include<stdio.h>
int main(){
  int i;
  char names[5][10]={"C","C++","JAVA","Python","PHP"};
  for(i=0;i<5;i++)  {
      printf("Program language:%s\n",names[i]);
  }
  return 0;
}

输出结果为
- Program language:C
- Program language:C++
- Program language:JAVA
- Program language:Python
- Program language:PHP

二维数组和一维数组的差距不大,具体还需实战操练,至于传递数组给函数,从函数返回数组,指向数组的指针,等后面说到函数和指针再说

结构体
数组只能定义相同类型数据项的变量,结构体更加灵活,用户可以自定义不同类型的数据项。常用于将不同类型的数据整合到一起,比如一个人的个人信息,用字符串表示姓名,地址,用整型表示年龄、身高和体重,用布尔表示性别等。
用 struct 语句来创建结构体, struct 语句的格式如下:
struct StructName {
member definition;
member definition;

member definition;
} [one or more structure variables];
StructName,结构体的名字,每个 member definition 是标准的变量定义,比如 int i; 或者 float f; 或者其他有效的变量定义。在结构体定义的末尾,最后一个分号之前,可以指定一个或多个结构体变量,也可以用
struct StructName variable 来定义结构体变量 。下面是定义Human以及声明结构体变量:
struct Human{
Bool sex;
char name[50];
char add[100];
int age, height, weight ;
} Lilei,HanMeimei;
struct Human WangJianlin;

访问结构体成员
用成员访问运算符(.)来访问结构体的成员。成员访问运算符是结构变量名称和所要访问的结构体成员之间的一个句号。下面演示用法:

 #include<stdio.h>
 #include <string.h>

struct Human{ 
bool sex; 
char name[50]; 
char add[100]; 
int age, height,weight ; 
} Lilei,HanMeimei;  //在定义结构体时声明两个结构体变量

int main( )
{
   struct Human WangJianlin;        // 声明 WangJianlin,类型为 Human 
   Lilei.sex = 0 ;
   strcpy( Lilei.name, "Lilei"); 
   strcpy( Lilei.add, "unknow"); 
   Lilei.age = 18;
   Lilei.height = 178;
   Lilei.weight = 65;
    printf("Li Lei's information\n");
    printf( "name : %s\n", Lilei.name);
   printf( "address : %s\n", Lilei.add);

   printf( "age: %d\n", Lilei.age);
   printf( "height : %d\n",  Lilei.height);
   printf("weight%d",Lilei.weight);
   return 0;
}

输出结果为:

  • Li Lei’s information
  • name : Lilei
  • address : unknow
  • age: 18
  • height :178
  • weight65

    至于结构体作为函数参数,指向结构体的指针,等到后面讲函数,指针时再细说,下面总结下列表、元组、数组和结构体的异同。

元组就是弱化版的列表,所以如果不是追求运行效率,或者非用元组,都用列表就好了。
列表可以当作数组,但比数组更强大也更方便,在Python中可以用Class关键字来实现类似结构体的功能,但结构体变量感觉和字典差不多,总之数据结构是独立于编程语言的,任何编程语言都能实现相同功能的数据结构,只是编程的难度以及运行效率不同,这也是为什么会有多种编程语言的原因。

限于所学有限,如果有任何纰漏之处,请各位指教。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值