python学习(第二章)

列表和元组

本章首先对序列做一个预览,接下来讲解所有序列(包括元组和列表)都通用的操作。而这些操作同样适用于字符串

序列概览

python包含6个内建序列,分别为列表、元组、字符串、Unicode字符串、buffer对象和xrange对象

  • 列表和元组的主要区别在于,列表可以修改,元组则不能

python中有一个名为容器(container)的数据结构。序列和映射是两类主要的容器。序列的每个元素都有自己的编号,而映射中的每个元素都有一个名字(即键)。


通用的序列操作

索引

  • 序列中的所有元素都是有编号的--从0开始递增。

    >>>greeting = 'Hello'
    >>>greeting[0]
    'H'
    
  • 使用负数索引时,python会从右边,也就是从最后1个开始计数

    >>>greeting[-1]
    'o'
    
  • 字符串字面值能够直接使用索引,而不需要一个变量引用它们。

    >>>'Hello'[1]
    'e'
    
  • 如果一个函数调用返回一个序列,那么可以直接对返回结果进行索引。

    >>>fourth = raw_input('Year: ')[3]
    Year: 2005
    >>>fourth
    '5'
    
  • 示例2-1:


 #根据给定的年 月 日以数字形式打印初日期
months = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December'
]
#以1~31的数字作为结尾的列表
endings = ['st', 'nd', 'rd'] + 17 * ['th'] \
+ ['st', 'nd', 'rd'] + 7 * ['th'] \
+ ['st']
year = raw_input('Year: ')
month = raw_input('Month (1-12): ')
day = raw_input('Day (1-31): ')
month_number = int(month)
day_number = int(day)
#记得要将月份和天数减1,以获得正确的索引
month_name = months[month_number - 1]
day_name = day + endings[day_number - 1]
print month_day + ' ' + day_name + ', ' + year


 $./2-1.py
Year: 2013
Month (1 - 12): 1
Day (1 - 31): 26
January 26th, 2013

分片

  • 与使用索引来访问单个元素类似,可以使用分片操作来访问一定范围的元素。分片通过冒号相隔的两个索引来实现

    >>>tag = '<a href="http://www.python.org">Python web site</a>'
    >>>tag[9: 30]
    'http://www.python.org'
    >>>tag[32: -4]
    'Python web site'
    
  • 第一个索引是需要提取部分的第一个元素的编号,而最后的索引则是分片之后剩下部分的第一个元素的编号

    >>>numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    >>>numbers[3: 6]
    [4, 5, 6]
    >>>numbers[0: 1]
    [1]
    
    1. 优雅的捷径

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

      实际上,只要分片中最左边的索引比它右边的晚出现在序列中,结果就是一个空序列。幸好,可以使用一个捷径:**如果分片所得部分包括序列结尾的元素,那么,组需置空最后一个索引即可

      这种方法同样使用于序列开始的元素:

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

      实际上,如果需要复制整个序列,可以将两个索引都置空:

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

    示例2-2:


     # 对http://www.something.org形式的URL进行分割
    url = raw_input('Please enter the URL: ')
    domain = url[11: -4]
    print "Domain name: " + domain
    


     Please enter the URL: http://www.baidu.com
    Domain name: baidu
    

    1. 更大的步长
      进行分片的时候,分片的开始和结束点需要进行制定。而另一个参数(在python2.3加入到内建类型)--步长(step length)--通常是隐式设置的。在普通的分片中,步长是1--分片操作就是按照这个步长逐个遍历序列的元素,然后返回开始和结束点之间的所有元素。

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

      当然,步长不能为0--那不会向下执行--当步长可以是负数,即从右到左提取元素,当在这里要求开始点(开始索引)大于结束点:

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

序列相加

  • 通过使用加号(+)可以进行序列的链接操作:

    >>>[1, 2, 3] + [4, 5, 6]
    [1, 2, 3, 4, 5, 6]
    >>>'Hello, ' + 'World'
    'Hello, World'
    
  • 列表和字符串是无法链接在一起的,尽管他们都是序列。简单的来说,两种相同类型的序列才能进行链接操作

    >>>[1, 2, 3] + 'world'
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    TypeError: can only concatenate list (not "str") to list
    

乘法

  • 用数字x乘以一个序列会产生新的序列,而在新的序列中,原来的序列将被重复x次。

    >>>'python' * 5
    'pythonpythonpythonpythonpython'
    >>>[42] * 10
    [42, 42, 42, 42, 42, 42, 42, 42, 42, 42]
    
None、空列表和初始化
  • 空列表可以通过两个中括号进行表示([])
  • 有时候需需要一个值来代表控制--意味着没有在里面放置任何元素。这个时候就需要使用None。None是一个python的内建值,它的确切含义是“这里什么也没有”。

    >>>sequence = [None] * 10
    >>>sequence
    [None, None, None, None, None, None, None, None, None, None]
    
  • 示例2-3


 # 以正确的跨度在居中的“盒子”内打印一个句子
# 注意,整数除法运算(//)只能在python2.2及后续版本,在之前的版本中,
# 只能使用普通除法(/)
sentence = raw_input('Sentence: ')
screen_width = 80
text_width = len(sentence)
box_width = text_width + 6
left_margin = (screen_width - box_width) // 2
print
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) + '+'
print


 $./2-3.py
Sentence: hello world
+---------------+
| |
| hello world |
| |
+---------------+

成员资格

  • 为了检查一个值是否在序列中,可以使用in运算符,**这个运算符检查某个条件是否为真,然后返回相应的值: 条件为真返回True,条件为假返回False。

    >>>permission = 'rw'
    >>>'w' in permission
    True
    >>>'x' in permission
    False
    >>>users = ['mlh', 'foo', 'bar']
    >>>raw_input('Enter your uesr name: ') in users
    Enter your uesr name: mlh
    True
    >>> subject = '$$$ Get rich now!!! $$$'
    >>> '$$$' in subject
    

    尝试去检查子字符串,只能用在python2.3及后续版本

  • 示例2-4


 # 检查用户名和PIN码
database = [
['albert', '1234'],
['dilbert', '4242'],
['smith', '7524'],
['jones', '9843']
]
username = raw_input('User name: ')
pin = raw_input('PIN code: ')
if [username, pin] in database: print 'Access granted'


 $./2-4.py
User name: albert
PIN code: 1234
Access granted

长度、最小值和最大值

  • 内建函数len、min和max

    >>>numbers = [1, 2, 3, 4]
    >>>len(numbers)
    4
    >>>max(numbers)
    4
    >>>min(numbers)
    1
    >>>max(2, 3)
    3
    >>>min(9, 2, 8, 4)
    2
    

列表: python的“苦力”

list函数

  • list函数可以实现: 根据字符串创建列表。

    >>>list('Hello')
    ['H', 'e', 'l', 'l', 'o']
    

    list函数适用于所有类型的序列,而不只是字符串


    可以用下面的表达式将一个由字符组成的序列转换成字符串:

    ''.join(somelist)
    

    在这里,somelist是需要转换的列表。


基本的列表操作

列表可以使用所有适用于序列的标准操作,例如索引、分片、连接和乘法。有趣的是,列表是可以修改的

修改列表: 元素赋值
  • 使用索引标记来为某个特定的、位置明确的元素赋值

    >>>x = [1, 1, 1]
    >>>x[1] = 2
    >>>x
    [1, 2, 1]
    

    [注: 不能为一个位置不存在额元素进行赋值。]

删除元素
  • 使用del语句从列表中删除元素

    >>>names = ['Alice', 'Beth', 'Cecil', 'Dee-Dee', 'Earl']
    >>>del names[2]
    >>>names
    ['Alice', 'Beth', 'Dee-Dee', 'Earl']
    
分片赋值
>>>name = list('Perl')
>>>name
['P', 'e', 'r', 'l']
>>>name[2: ] = list('ar')
>>>name
['P', 'e', 'a', 'r']
  • 在使用分片赋值时,可以使用与原序列不等长的序列将分片替换。

    >>>name = list('Perl')
    >>>name[1: ] = list('ython')
    >>>name
    ['P', 'y', 't', 'h', 'o', 'n']
    
  • 通过分批赋值来删除元素也是可行的: "替换"一个空的分片。

    >>>numbers = [1, 2, 3, 4, 5]
    >>>numbers[1: 4] = []
    >>>numbers
    [1, 5]
    
列表方法
  • 方法是一个与某些对象有紧密联系的函数,对象可能是列表、数字,也可能是字符串或者其他类型对象。一般来说,方法可以这样进行调用:

    对象.方法(参数)
    
    1. append
      append方法用于在列表末尾追加新的对象:

      >>>lst = [1, 2, 3]
      >>>lst.append(4)
      >>>lst
      [1, 2, 3, 4]
      >>> lst.append([4, 5, 6])
      >>> lst
      [1, 2, 3, [4, 5, 6]]
      
    2. count
      count方法统计某个元素在列表中出现的次数

      >>>['to', 'be', 'or', 'not', 'to', 'be'].count('to)
      2
      >>>x = [[1, 2], 1, 1, [2, 1, [1, 2]]]
      >>>x.count(1)
      2
      >>>x.count([1, 2])
      1
      
    3. extend
      extend方法可以在列表的末尾一次追加一个序列中的多个值。

      >>>a = [1, 2, 3]
      >>>a.extend([4, 5, 6])
      >>>a
      [1, 2, 3, 4, 5, 6]
      

      这个操作看起来很像连接操作,两者最主要区别在于: extend方法修改了被扩展的序列; 而原始的链接这不然,它会返回一个全新的序列

      >>>a = [1, 2, 3]
      >>>b = [4, 5, 6]
      >>>a + b
      [1, 2, 3, 4, 5, 6]
      >>>a
      [1, 2, 3]
      >>>b
      [4, 5, 6]
      >>>a.extend(b)
      >>>a
      [1, 2, 3, 4, 5, 6]
      

      使用a.extend(b)等价于a[len(a): ] = b,即使用分片赋值来实现相同的结果。

    4. index
      index方法用于从列表中找出某个值第一个匹配项的索引位置:

      >>>knights = ['We', 'are', 'the', 'knights', 'who', 'say', 'ni']
      >>>knights.index('who')
      4
      >>>knights.index('herring')
      Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      ValueError: 'herring' is not in list
      
    5. insert
      insert方法用于将对象插入到列表中:

      >>>numbers = [1, 2, 3, 5, 6, 7]
      >>>numbers.insert(3, 'four')
      >>>numbers
      [1, 2, 3, 'four', 5, 6, 7]
      

      使用numbers.insert(3, 'four')等价于numbers[3: 3] = 'four',即用分片赋值来实现。

      >>>numbers = [1, 2, 3, 6, 7]
      >>>numbers.insert(3,
      
    6. pop
      pop方法会移除列表中的一个元素(默认是最后一个),并且返回该元素的值

      >>>x = [1, 2, 3]
      >>>x.pop()
      >>>3
      >>>x
      [1, 2]
      >>>x.pop(0)
      1
      >>>x
      [2]
      

      [注: pop方法是唯一一个既能修改列表有返回元素值(除了None)的列表]

      pop方法可以实现出栈方法,而python没有入栈方法,但可以使用append方法来代替。pop方法和append方法的操作恰好相反。

      >>>x = [1, 2, 3]
      >>>x.append(x.pop())
      >>>x
      [1, 2, 3]
      

      如果需要实现一个FIFO的队列,那么可以使用insert(0, ...)来代替append方法。或者,也可以继续使用append方法,但必须用pop(0)来代替pop()。更好的解决方案是使用collectin模块中deque对象)

    7. remove
      remove方法用于一处列表中某个值的第一个匹配项

      >>>x = ['to', 'be', 'or', 'not', 'to', 'be']
      >>>x.remove('be')
      >>>x
      ['to', '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是一个没有返回值的原位置改变方法。它修改了列表却没有返回值,这与pop方法相反。

    8. reverse
      reverse方法将列表中的元素反向存放:

      >>>x = [1, 2, 3]
      >>>x.reverse()
      >>>x
      [3, 2, 1]
      

      reverse方法改变了列表但不返回值(就像remove和sort)

    9. sortsort方法用于在原位置对列表进行排序。

      >>>x = [4, 6, 2, 1, 7, 9]
      >>>x.sort()
      >>>x
      [1, 2, 4, 6, 7, 9]
      

      sort返回了x但返回了空值

      >>>x = [4, 6, 2, 1, 7, 9]
      >>>y = x[: ]
      >>>y.sort()
      >>>x
      [4, 6, 2, 1, 7, 9]
      >>>y
      [1, 2, 4, 6, 7, 9]
      

      再次强调调用x[: ]得到的是包含了x所有元素的分片,这是一种很有效的复制整个列表的方法。只是简单的吧x赋值给y是没用的,因为这样做就让x和y都指向同一个列表

      >>>x = [4, 6, 2, 1, 7, 9]
      >>>y = x
      >>>y.sort()
      >>>x
      [1, 2, 4, 6, 7, 9]
      >>>y
      [1, 2, 4, 6, 7, 9]
      

      另一种获得已排序的列表副本的方法是,使用sorted函数:

      >>>x = [4, 6, 2, 1, 7, 9]
      >>>y = sorted(x)
      >>>x
      [4, 6, 2, 1, 7, 9]
      >>>y
      [1, 2, 4, 6, 7, 9]
      

      sorted实际上可以用于任何序列,却总是返回一个列表:

      >>>sorted('Python')
      ['P', 'h', 'n', 'o', 't', 'y']
      
    10. 高级排序
      如果希望元素能按照特定的方式进行排序(而不是sort函数默认的方式,而根据python默认排序规则按升序排列元素),那么可以通过compare(x, y)的形式自定义比较函数。compare(x, y)函数会在x < y时返回复制, 在x > y时返回正值,如果x = y则返回0。定义好该函数之后,就可以提供给sort方法作为参数了。内建函数cmp提供了比较函数的默认实现方式:

      >>>cmp(42, 32)
      1
      >>>cmp(99, 100)
      -1
      >>>cmp(10, 10)
      0
      >>>numbers = [5, 2, 7, 9]
      >>>numbers.sort(cmp)
      >>>numbers
      [2, 5, 7, 9]
      

      sort方法有另为两个可选参数--key和reverse。如果要使用它们,那么就要通过名字来指定。* 如果要根据元素的长度进行排序,那么可以使用len作为键函数:

       >>>x = ['aaedvark', 'abalone', 'acme', 'add', 'aerate']
      >>>x.sort(key=len)
      >>>x
      ['add', 'acme', 'aerate', 'abalone', 'aardvark']
      * 另一个关键字参数reverse是简单的布尔值(True或False),用来指明
      列表是否要进行反向排序:
      >>>x = [4, 6, 2, 1, 7, 9]
      >>>x.sort(reverse = True)
      >>>x
      [9, 7, 6, 4, 2, 1]
      

元组: 不可变序列

元组与序列一样,也是一种序列。唯一的不同是元组不能修改。(可以注意到,字符串也是如此。)创建元组的语法: 用逗号分隔一些值,那么就自动创建了元组。

>>>1, 2, 3
(1, 2, 3)

元组也是(大部分时候)通过圆括号起来的:

>>>(1, 2, 3)
(1, 2, 3)

空元组可以用没有包含内容的两个圆括号来表示:

>>>()
()

创建包含一个值的元组。实现方法有些奇特--必须加个逗号,即使只有一个值:

>>>42
42
>>>42,
(42,)
>>>(42,)
(42,)

一个逗号能彻底地改变表达式的值:

>>>3 * (40 + 2)
126
>>>3 * (40 + 2, )
(42, 42, 42)

tuple函数

  • tuple函数的功能与list函数基本上是一样的: 以一个序列作为参数并把它转换为元组。

    >>>tuple([1, 2, 3])
    (1, 2, 3)
    >>>tuple('abc')
    ['a', 'b', 'c']
    >>>tuple((1, 2, 3))
    (1, 2, 3)
    

基本元组操作

  • 元组其实并不复杂--除了创建元组和访问元组元素之外,也没有太多其他擦做,可以参照其他类型的序列来实现:

    >>>x = 1, 2, 3
    >>>x[1]
    2
    >>>x[0: 2]
    (1, 2)
    

那么, 意义何在

  • 元素可以在映射(和集合的成员)中当作键使用--而列表则不行
  • 元组作为很多内建函数和方法的返回值存在,也就是说必须对元组进行处理。只要不尝试修改元组,那么,"处理"元组在绝大数情况下就是把它们当作列表进行操作

新函数

本章的新函数函数 & 描述\cmp(x, y) & 比较两个值\len(seq) & 返回序列的长度\list(seq) & 把序列转换成列表\max(args) & 返回序列或参数集合中的最大值\min(args) & 返回序列或参数集合中的最小值\reversed(seq) & 对序列进行反向迭代\sorted(seq) & 返回以排序的包含seq所有元素的列表\tuple(seq) & 把序列转换成组\

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值