列表
>>> []!! ! ! ! ! ! ! # 空列表。
[]
>>> ['a', 'b'] * 3! ! ! ! ! ! # 这个少见吧。
['a', 'b', 'a', 'b', 'a', 'b']
>>> ['a', 'b'] + ['c', 'd']! ! ! ! # 连接多个列表。
['a', 'b', 'c', 'd']
>>> list("abcd")! ! ! ! ! ! # 将序列类型或迭代器转换为列表。
['a', 'b', 'c', 'd']
>>> [x for x in range(3)]!! ! ! ! # 生成器表达式。
[0, 1, 2]
>>> l = list("abc")
>>> l[1] = 2 # 按序号读写。
>>> l
['a', 2, 'c']
>>> l = list(xrange(10))
>>> l[2:-2] # 切⽚片。
[2, 3, 4, 5, 6, 7]
>>> l = list("abcabc")
>>> l.count("b") # 统计元素项。
2
>>> l = list("abcabc")
>>> l.index("a", 2) # 从指定位置查找项,返回序号。
3
>>> l = list("abc")
>>> l.append("d")
>>> l # 追加元素。
['a', 'b', 'c', 'd']
>>> l = list("abc")
>>> l.insert(1, 100) # 在指定位置插⼊入元素。
>>> l
['a', 100, 'b', 'c']
>>> l = list("abc")
>>> l.extend(range(3)) # 合并列表。
>>> l
['a', 'b', 'c', 0, 1, 2]
>>> l = list("abcabc")
>>> l.remove("b") # 移除第⼀一个指定元素。
>>> l
['a', 'c', 'a', 'b', 'c']
>>> l = list("abc")
>>> l.pop(1) # 弹出指定位置的元素 (默认最后项)。
'b'
>>> l
['a', 'c']
>>> import bisect
>>> l = ["a", "d", "c", "e"]
>>> l.sort()
>>> l
['a', 'c', 'd', 'e']
>>> bisect.insort(l, "b")
>>> l
['a', 'b', 'c', 'd', 'e']
>>> bisect.insort(l, "d")
>>> l
['a', 'b', 'c', 'd', 'd', 'e']
支持倒序。
>>> x[::-1]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>> x[7:3:-2]
[7, 5]
性能
列表用 realloc() 调整指针数组内存大小,可能需要复制数据。插入和删除操作,还会循环移动后
续元素。这些都是潜在的性能隐患。对于频繁增删元素的大型列表,应该考虑用链表等数据结构代
替。
下面的例子测试了两种创建列表对象方式的性能差异。为获得更好测试结果,我们关掉 GC,元素
使用同一个小整数对象,减少其他干扰因素。
>>> import itertools, gc
>>> gc.disable()
>>> def test(n):
... return len([0 for i in xrange(n)]) # 先创建列表,然后 append。
>>> def test2(n):
... return len(list(itertools.repeat(0, n))) # 按照迭代器创建列表对象,一次分配内存。
>>> timeit test(10000)
1000 loops, best of 3: 810 us per loop
>>> timeit test2(10000)
10000 loops, best of 3: 89.5 us per loop
可以使用数组提高读写效率
>>> import array
>>> a = array.array("l", range(10)) # ⽤用其他序列类型初始化数组。
>>> a
array('l', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> a.tolist() # 转换为列表。
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a = array.array("c") # 创建特定类型数组。
>>> a.fromstring("abc") # 从字符串添加元素。
>>> a
array('c', 'abc')
>>> a.fromlist(list("def")) # 从列表添加元素。
>>> a
array('c', 'abcdef')
>>> a.extend(array.array("c", "xyz")) # 合并列表或数组。
>>> a
array('c', 'abcdefxyz')
Timeit使用
timeit 模块定义了接受两个参数的 Timer 类。两个参数都是字符串。 第一个参数是你要计时的语句或者函数。 传递给 Timer 的第二个参数是为第一个参数语句构建环境的导入语句。 从内部讲, timeit 构建起一个独立的虚拟环境, 手工地执行建立语句,然后手工地编译和执行被计时语句。
一旦有了 Timer 对象,最简单的事就是调用 timeit(),它接受一个参数为每个测试中调用被计时语句的次数,默认为一百万次;返回所耗费的秒数。
Timer 对象的另一个主要方法是 repeat(), 它接受两个可选参数。 第一个参数是重复整个测试的次数,第二个参数是每个测试中调用被计时语句的次数。 两个参数都是可选的,它们的默认值分别是 3 和 1000000。 repeat() 方法返回以秒记录的每个测试循环的耗时列表。Python 有一个方便的 min 函数可以把输入的列表返回成最小值,如: min(t.repeat(3, 1000000))
你可以在命令行使用 timeit 模块来测试一个已存在的 Python 程序,而不需要修改代码。
具体可参见文档: http://docs.python.org/library/timeit.html
# -*- coding: utf-8 -*-
from timeit import Timer
def test1():
n=0
for i in range(101):
n+=i
return n
def test2():
return sum(range(101))
def test3():
return sum(x for x in range(101))
if __name__=='__main__':
t1=Timer("test1()","from __main__ import test1")
t2=Timer("test2()","from __main__ import test2")
t3=Timer("test3()","from __main__ import test3")
print t1.timeit(10000)
print t2.timeit(10000)
print t3.timeit(10000)
print t1.repeat(3,10000)
print t2.repeat(3,10000)
print t3.repeat(3,10000)
元组
元组 (tuple) 看上去像列表的只读版本,但在底层实现上有很多不同之处。• 只读对象,元组和元素指针数组内存是一次性连续分配的。
• 虚拟机缓存 n 个元素数量小于 20 的元组复用对象。
在编码中,应该尽可能用元组代替列表。除内存复用更高效外,其只读特征更利于并行开发
>>> a = (4) # 少了逗号,就成了普通的括号运算符了。
>>> type(a)
<type 'int'>
>>> a = (4,) # 这才是元组。
>>> type(a)
<type 'tuple'>
>>> s = tuple("abcadef") # 将其他序列类型转换成元组。
>>> s
('a', 'b', 'c', 'a', 'd', 'e', 'f')
>>> s.count("a") # 元素统计。
2
>>> s.index("d") # 查找元素,返回序号。
4
还可以使用namedtuple,可用名字访问元素项
>>> from collections import namedtuple
>>> User = namedtuple("User", "name age") # 空格分隔字段名,或使用迭代器。
>>> u = User("user1", 10)
>>> u.name, u.age
('user1', 10)