zoukankan      html  css  js  c++  java
  • python笔记02:列表与元素

    本章将引入一个新的概念:数据结构。数据结构是通过某种方式(例如对元素进行编号)组织在一起的数据元素的集合。这些数据元素可以是数字或者字符,甚至可以是其他数据结构。在python中,最基本的数据结构是序列。序列中的每个元素被分配一个序号--即元素的位置,也称为索引。第一个索引为0,第二个1,以此类推。序列中的最后一个数被标志为-1,倒数第二个为-2,。。。。

    2.1 序列概览:

    python有6种内建的序列,其中常见的两种序列:列表和元组,其他的有字符串,Unicode字符串,buffer对象和xrange对象
    >>> edward = ['John Smith',50]
    >>> Ads = ['Edward Gumdy',42]
    >>> database = [edward,Ads]
    >>> database
    [['John Smith', 50], ['Edward Gumdy', 42]]

    python中还有一种名为容器的数据结构。容器基本上是包含其他数据对象的任意对象。序列(例如列表和元组)和映射(例如字典)是两列最主要的容器。序列中每个元素都有自己的编号,而映射中的每个元素则有一个名字(也成为键)

    2.2 通用序列操作

    所有序列烈性都可以进行某些特定的操作。这些操作包括:索引、分片、加、乘以及检查某个元素是否属于序列的成员。
    除此之外,python还有计算序列长度、找出最大元素和最小元素的内建函数。
    还有迭代,即一次对序列中的每个元素重复进行某些操作

    2.2.1 索引

    序列中的手游元素都是有编号的---从0开始递增。这些元素可以通过编号分别进行访问,如下所示:
    >>> greeting = 'hello'
    >>> greeting[0]
    'h'
    >>> greeting[-1]
    'o'
    >>> test = "This is a test!"
    >>> test[0]
    'T'
    >>> test = ['abc','123','@@@','xyz']
    >>> test[0]
    'abc'
    >>> test[-2]
    '@@@'
    >>> abc[-1]
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'abc' is not defined
    >>> 'abc'[-1]
    'c'
    >>> 'xyz','abc'[0]
    ('xyz', 'a')
    >>> 'xyz','abc'[-1]
    ('xyz', 'c')
    >>> ['xyz','abc'][-1]
    'abc'

    以下是一个脚本示例:

    # -*- coding:utf-8 -*-
    #根据给定的年月日以数字形式打印出日期
    months = [
        'January',
        'February',
        'March',
        'April',
        'May',
        'June',
        'July',
        'August',
        'September',
        'October',
        'November',
        'December'
    ]
    #以1-31的数字作为结尾的列表
    ending = ['st','nd','rd'] + 17 * ['th']
           + ['st','nd','rd'] + 7 * ['th']
           + ['st']
    
    year  = raw_input('Year: ')
    month = raw_input('Month: ')
    day   = raw_input('Day: ')
    month_num = int(month)
    day_num = int(day)
    
    #记得要将月份与天数减1,已获得正确的索引
    month_name = months[month_num - 1]
    ordinal = day + ending[day_num - 1]
    
    print month_name + ' ' + ordinal + '.' + year

    输出如下:

    Year: 1223
    Month: 12
    Day: 20
    December 20th.1223

    2.2.3 分片

    与使用索引来访问单个元素类似,可以使用分片操作来访问一定范围内的元素。分片通过冒号隔开的两个索引来实现:
    >>> numbers = [1,2,3,4,5,6,7,8]
    >>> numbers[3:6]
    [4, 5, 6]
    >>> numbers[0:2]
    [1, 2]
    >>> numbers[0:1]
    [1]
    >>> numbers[7:10]
    [8]
    >>> numbers[-3:0]
    []
    >>> numbers[-3:-1]
    [6, 7]
    >>> numbers[-3]
    6
    >>> numbers[-3:]
    [6, 7, 8]
    >>> numbers[:3]
    [1, 2, 3]
    >>> numbers[:]
    [1, 2, 3, 4, 5, 6, 7, 8]

    步长的概念:进行分片时,分片的开始和结束点需要进行指定(不管是直接还是间接),而另一个参数--步长--通常是隐式设置的。示例如下:

    >>> num = [1,2,3,4,5,6,7,8,9,10]
    >>> num[1:10:1]
    [2, 3, 4, 5, 6, 7, 8, 9, 10]
    >>> num[1:10:2]
    [2, 4, 6, 8, 10]
    >>> num[3:6:2]
    [4, 6]
    >>> num[::4]
    [1, 5, 9]
    >>> num[8:3:-1]
    [9, 8, 7, 6, 5]
    >>> num[10:0:-3]
    [10, 7, 4]
    >>> num[::-2]
    [10, 8, 6, 4, 2]
    >>> num[5::-2]
    [6, 4, 2]
    >>> num[:5:-2]
    [10, 8]

    需要注意:

    1.开始点的元素(最左边的)包括在结果中,而结束点的元素(最右边的)则不再分片中
    2.当使用一个负数作为步长时,必须让开始点的索引大于结束点
    3.在没有明确指定开始与结束点的时候,正负数的使用可能会带来一些混淆

    2.2.3 序列相加

    >>> [1,2,3] + [abc,xyz,test]
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'abc' is not defined
    >>> [1,2,3] + ['abc','xyz','test']
    [1, 2, 3, 'abc', 'xyz', 'test']
    >>> 'hello,' + 'World'
    'hello,World'
    >>> [1,2,3] + 'abc'     #列表与字符串是无法连接在一起的,尽管他们都是序列,但不是同一类型
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: can only concatenate list (not "str") to list

    2.2.4 乘法

    只能用数字与序列的乘法,原来的序列将会被重复n次
    >>> ['abc','xyz'] * 3
    ['abc', 'xyz', 'abc', 'xyz', 'abc', 'xyz']
    >>> 'python ' * 3
    'python python python '

    空列表:空列表可以简单的通过两个中括号来表示,里面什么都没有。

    但是如果想创建一个占用10个元素空间,却不包含任何有效内容的列表,该怎么办?
    可以像前面那样使用[42]*10或[0]*10,这样就生成了一个包含10个0的列表
    None:有时会需要一个值来代表空值,意味着没有在里面放置任何元素,这时候就需要使用None。None是python的一个内建值,他的确切含义是“什么都没有”。因此,可以用来初始化列表。
    示例如下:
    >>> sequence = [None] * 10
    >>> sequence
    [None, None, None, None, None, None, None, None, None, None]

    用代码打印一个盒子:

    # -*- coding:utf-8 -*-
    #以正确的宽度唉居中的“盒子”内打印一个句子
    #注意:整数除法"//"只能用在python2.2以后
    sentence = raw_input("Sentence: ")
    
    screen_width = 40
    text_width = len(sentence)
    box_width = text_width + 6
    left_margin = (screen_width - box_width)//2
    
    print ' ' * left_margin + '+' + '-' * (box_width-2) + '+'
    print ' ' * left_margin + '|' + ' ' * text_width   + ' |'
    print ' ' * left_margin + '|' +       sentence     + ' |'
    print ' ' * left_margin + '|' + ' ' * text_width   + ' |'
    print ' ' * left_margin + '+' + '-' * (box_width-2) + '+'
    输出如下:
    Sentence: This is a Test!
             +-------------------+
             |                |
             |This is a Test! |
             |                |
             +-------------------+

    2.2.5 成员资格

    为了检查一个值是否在序列中,可以使用in运算符,用来检测某个条件是否为主,然后返回相应的值
    >>> 'W' in 'world'
    False
    >>> 'W' in 'World'
    True
    >>> user = ['abc','Slar','Stant']
    >>> raw_input("What's your name ?") in user
    What's your name ?Slar
    True
    >>> subject = '$$$ Get rich now! $$$'
    >>> '$$$' in subject
    True

    在Unix系统中,我们可以使用in来检查用户是否有某些权限,还可以用来检测用户的帐号密码是否对应的上

    示例脚本如下:
    # -*- coding:utf-8 -*-
    database = [
        ['albert','1234'],
        ['Andy','abc123'],
        ['smith','76420'],
        ['Lily','678900']
    ]
    
    username = raw_input("Please input your name: ")
    pin      = raw_input("Please input your pin number: ")
    if [username,pin] in database:
        print "Access granted."
    else:
        print "Something is wrong!"

    输出如下:

    [root@node1 2]# python ex2-4.py
    Please input your name: Andy
    Please input your pin number: abc123
    Access granted.
    [root@node1 2]# python ex2-4.py
    Please input your name: Andy
    Please input your pin number: 123123
    Something is wrong!

    2.2.6 长度,最大值,最小值

    内建函数len,max,min
    >>> num = [100,20,3088]
    >>> len(num)
    3
    >>> max(num)
    3088
    >>> min(num)
    20
    >>> str = [100,abc,230,xyz]

    2.3 列表

    2.3.1 list函数

    因为字符串不能像列表一样修改,索引有时根据字符串创建列表会很有效。list函数
    >>> list('hello')
    ['h', 'e', 'l', 'l', 'o']
    >>> list('123456')
    ['1', '2', '3', '4', '5', '6']

    2.3.2 列表的基本操作

    1.改变列表:元素赋值
    2.删除元素:del
    >>> x = [1,2,3,45,32]
    >>> x[1]
    2
    >>> x[1] = 243 #直接赋值改变元素
    >>> x
    [1, 243, 3, 45, 32]
    >>> del x[1]   #删除元素
    >>> x
    [1, 3, 45, 32]
    3.分片赋值:
    >>> name = list('perl')
    >>> name
    ['p', 'e', 'r', 'l']
    >>> name[2:]
    ['r', 'l']
    >>> name[2:] = list('ar') #程序可以一次为多个元素进行赋值
    >>> name
    ['p', 'e', 'a', 'r']
    >>> num = [1,5]
    >>> num[1:1] = [2,3,4]    #分片替换可以在不需要替换任何原有元素的情况下插入新的元素
    >>> num
    [1, 2, 3, 4, 5]
    >>> num[2:3] = []   #当然也可以用来批量删除元素
    >>> num
    [1, 2, 4, 5]

    2.3.3 列表方法

    1.追加:append
    在列表末尾追加新的元素
    >>> test = [1,2,3]
    >>> test.append('abc')
    >>> test
    [1, 2, 3, 'abc']
    >>> test.append(5)
    >>> test
    [1, 2, 3, 'abc', 5]
    2.统计:count
    用来统计某个元素在列表中出现的次数
    >>> a = [1,234,21,34,[123,1],1,2]
    >>> a.count(1)
    2
    >>> a.count([123,1])
    1
    3.扩展:entend
    在列表的末尾一次性追加另一个序列的多个值
    这个操作看起来很想连接操作,两者最主要的区别在于:extend方法修改了被扩展的序列。而原始的连接则不然,他会返回一个全新的列表
    >>> a = [1,2,3]
    >>> b = [4,5,6]
    >>> a.extend(b)
    >>> a
    [1, 2, 3, 4, 5, 6]   #a的值已经被改变
    >>> a + b            #a的值并未被改变
    [1, 2, 3, 4, 5, 6, 4, 5, 6]
    >>> a[len(a):] = b   #可以用分片赋值来实现相同的操作,但不推荐使用
    >>> a
    [1, 2, 3, 4, 5, 6, 4, 5, 6]
    4.索引:index
    用于从列表中找出某个值第一个匹配项的索引位置
    >>> test = ['This','is','a','test']
    >>> test.index('test')
    3
    >>> test.index('q')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError: list.index(x): x not in list
    5.插入:insert
    用于将对象插入到列表中
    >>> num
    [1, 2, 4, 5]
    >>> num.insert(3,'test')
    >>> num
    [1, 2, 4, 'test', 5]
    与extend方法类似,insert方法的操作也可以用分片赋值来实现
    6.移除:pop
    会移除列表中的一个元素(默认是最后一个),并且返回该元素的值
    >>> num
    [1, 2, 4, 'test', 5]
    >>> num.pop()
    5
    >>> num.pop(3)
    'test'
    >>> num
    [1, 2, 4]
    使用pop方法可以实现一种常见的数据结构--栈,即后进先出的移除数据。实现入栈和出栈
    >>> num
    [1, 2, 4]
    >>> num.append(num.pop())
    >>> num
    [1, 2, 4]
    7.移除:remove
    用于移除列表中某个值的第一个匹配项
    >>> x = "to be or not to be".split()
    >>> x
    ['to', 'be', 'or', 'not', 'to', 'be']
    >>> x.remove('to')
    >>> x
    ['be', 'or', 'not', 'to', 'be']
    >>> x.remove('bee')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError: list.remove(x): x not in list
    可以看到:只有第一次出现的值被移除了,而不存在与列表中的值是不会被移除的
    值得注意的是:remove是一个没有返回值的原位置改变方法,他修改了列表却没有返回值
    8.反向存放:reverse
    将列表中的元素反向存放
    >>> x
    ['This', 'is', 'a', 'test']
    >>> x.reverse()
    >>> x
    ['test', 'a', 'is', 'This']
    9.排序:sort
    用于在原位置对列表进行排序,从而让其中的元素能按一定的顺序排列,而不是简单的返回一个已排序的列表副本。sort并不返回排序好的列表!
     
    当用户需要一个排号序的副本,同时又要求保留列表不变时:
    第一种方法:
    >>> x = [1,2,5,3,7,4,9,8,0]
    >>> x.sort()
    >>> x
    [0, 1, 2, 3, 4, 5, 7, 8, 9]
    >>> x = "This is a test".split()
    >>> x.sort()
    >>> x
    ['This', 'a', 'is', 'test']
    第二种方法:
    >>> x = [1,2,5,3,9]
    >>> y =sorted(x)
    >>> x
    [1, 2, 5, 3, 9]
    >>> y
    [1, 2, 3, 5, 9]
    而使用另一种则不行:
    >>> x = [1,2,5,3,7,4,9,8,0]
    >>> y = x
    >>> y.sort()
    >>> x
    [0, 1, 2, 3, 4, 5, 7, 8, 9]
    >>> y
    [0, 1, 2, 3, 4, 5, 7, 8, 9]
    10 高级排序
    如果希望元素能够按照特定的发放时进行排序(而不是sort函数默认的方式,及根据python的默认顺序进行排序),那么就可以通过compare(x,y)的形式自定义比较函数。compare(x,y)会在x<y时返回负数,x>y时返回证书,如果x=y则返回0(根据你自己的定义)。定义好该函数之后,就可以提供给sort方法作为参数了。内建函数cmp提供了比较函数的默认实现方式:
    cmp函数:
    >>> cmp(32,42)
    -1
    >>> cmp(-1,1)
    -1
    >>> cmp(1,-1)
    1
    >>> cmp(1,1)
    0
    使用cmp参数排序:
    >>> numbers = [2,5,9,7]
    >>> numbers.sort(cmp)
    >>> numbers
    [2, 5, 7, 9]
    sort方法还有另外两个可选的参数-key和reverse。如果要使用他们,就要通过名字来指定(即关键字参数)。参数key与cmp类似--必须提供一个在排序过程中使用的函数。然而,该函数并不是直接用来确定对象的大小,而是为每个元素创建一个键,然后所有元素根据键来排序。因此,如果要根据元素的长度进行排序,那么可以使用len作为键函数:
    >>> x=['address','abalone','acme','add','aerate']
    >>> x.sort(key=len)
    >>> x
    ['add', 'acme', 'aerate', 'address', 'abalone']
    使用reverse:
    >>> x = [4,6,1,7,9]
    >>> x.sort(reverse=True)
    >>> x
    [9, 7, 6, 4, 1]
    cmp与key、reverse参数都可以作为sorted的函数,在多数情况下,为cmp或key提供自定义函数是非常有用的

    2.4 元组:不可变序列

    元组与列表一样,也是一种序列。唯一的不同是元组不能修改。创建元组的语法很简单,如果你用逗号分割了一些值,那么它就自动创建了元组。
    >>> 1,2,3    #定义一个元组
    (1, 2, 3)
    >>> (1,2,3,4)
    (1, 2, 3, 4)
    >>> ()       #一个空元组
    ()
    >>> 42,      #只含有一个值的元组
    (42,)
    >>> 42
    42
    元组大部分时候是通过圆括号括起来的,空元组可以用没有包含内容的两个圆括号来表示,而对于只有一个值的元组,必须加一个逗号,逗号是非常重要的,只添加圆括号是没用的,如下:
    >>> 3*(40+2)
    126
    >>> 3*(40+2,)
    (42, 42, 42)

    2.4.1 tuple函数

    tuple函数功能与list函数基本上是一样的,以一个序列作为参考并把它转换为元组,如果参数就是元组,那么该参数就会被原样返回:
    >>> tuple([1,2,3,4])
    (1, 2, 3, 4)
    >>> tuple((1,2,3,4))
    (1, 2, 3, 4)
    >>> tuple('addrss')
    ('a', 'd', 'd', 'r', 's', 's')

    2.4.2 基本元组操作:

    除了创建元组与访问元组元素之外,因为没有太多其他操作,可以参照其他类型的序列来实现:
    >>> x = 1,2,3
    >>> x[1]
    2
    >>> x[0:2]
    (1, 2)

    2.4.3 元组的意义何在?

    1.元组可以在映射(和集合的成员)中当作键使用--而列表不行
    2.元组作为很多内建函数和方法的返回值存在,也就是说你必须对元组进行处理。只要不尝试修改元组,那么,“处理”
    元组在绝大多数情况下就是把他们当作列表来进行操作
    一般来说,列表可能更能满足对序列的所有需求

    2.5 小结

    函数 描述
    cmp(x,y) 比较两个数的值
    len(seq) 返回序列的长度
    lsit(seq) 把序列转化为列表
    max(args) 返回序列或参数集合中的最大值
    min(args) 返回序列或参数集合中的最小值
    reverse(seq) 对序列进行反向迭代
    sorted(seq) 返回已排序的包含seq所有元素的列表
    tuple(seq) 把序列转化为元组
     
  • 相关阅读:
    浅谈css中的盒模型(框模型)
    Linux 字符设备驱动及一些简单的Linux知识
    java实现person类 override(重写) comparable接口
    java之内部类
    mac下sublime text3 安装px转rem插件
    python pip安装扩展报错
    curl http_code 状态码
    sed 批量替换文件
    centos 7 开机优化shell
    一个tcp连接可以发多少http请求
  • 原文地址:https://www.cnblogs.com/zhangpf/p/7593628.html
Copyright © 2011-2022 走看看