Python:list,tuple,dict

最新更新发布在http://www.ttwshell.com/article/Python-3.X-2.X-Diff-List-Tuple-Dict.html 包含了2.X和3.X的所有API对比。

一、list方法详解!

Help on class list in module __builtin__:

class list(object)
 |  list() -> new empty list   # list() 建立一个空list,工厂函数

 |  list(iterable) -> new list initialized from iterable's items # 返回一个以迭代器里的所有元素新建的list!以下是例子。

>>> list([1,2,3,4])
[1, 2, 3, 4]
>>> list((1,2,3,4))
[1, 2, 3, 4]
>>> list("1234")
['1', '2', '3', '4']

 |  Methods defined here:
 |  
 |  append(...)   # 添加一个对象在list末尾
 |      L.append(object) -- append object to end
 |  
 |  count(...) # 返回list中指定对象的个数,没有指定报错
 |      L.count(value) -> integer -- return number of occurrences of value
 |  
 |  extend(...)   # 把迭代器中的所有元素添加到原list的末尾
 |      L.extend(iterable) -- extend list by appending elements from the iterable
>>> l = [1, 2, 3, 4, 2, 5, 5, 2, 3, 6]
>>> a = ("a", 1, "dd")
>>> l.extend(a)
>>> l
[1, 2, 3, 4, 2, 5, 5, 2, 3, 6, 'a', 1, 'dd']
 |  index(...)   # 返回第一个value的下标!如果value不存在,报错!
 |      L.index(value, [start, [stop]]) -> integer -- return first index of value. #  [start, [stop]]为指定起止下标号
 |      Raises ValueError if the value is not present.
 |  
 |  insert(...) # 在下标index前面插入一个对象!
 |      L.insert(index, object) -- insert object before index
 |  
 |  pop(...)   # 按下标号pop掉一个对象!并返回这个对象! 如果下表不存在为空则抛出一个IndexError!
 |      L.pop([index]) -> item -- remove and return item at index (default last).
 |      Raises IndexError if list is empty or index is out of range.
 |  
 |  remove(...) # 删除掉第一个为value的值!如果有多个,也只删除第一个!值不存在则抛出异常!
 |      L.remove(value) -- remove first occurrence of value.
 |      Raises ValueError if the value is not present.
 |  
 |  reverse(...) # 反转,也就是倒排序!经常有人问反转怎么做。。。
 |      L.reverse() -- reverse *IN PLACE*
 |  
 |  sort(...) # 排序,排序规则为,先数字,后字母,涉及到中文的话,很复杂,因为各种编码的关系,暂时未涉及,不做讨论。【猜测应该是对应编码的二进制表示相关!错了请指正】
 |      L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;
 |      cmp(x, y) -> -1, 0, 1
>>> l
[1, 3, 4, 2, 5, 5, 2, 3, 6, 'a', 1, 'dd']
>>> l.reverse()
>>> l
['dd', 1, 'a', 6, 3, 2, 5, 5, 2, 4, 3, 1]
>>> l.sort()
>>> l
[1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 'a', 'dd']
>>> 

1.1 把链表当作队列使用

你也可以把链表当做队列使用,队列是这样的数据结构,最先进入的元素最先释放(先进先出)。使用 append()方法可以把元素添加到队列最后,以0为参数调用pop()方法可以把最先进入的元素释放出来。例如:
>>> queue = ["Eric", "John", "Michael"]
>>> queue.append("Terry") # Terry arrives
>>> queue.append("Graham") # Graham arrives
>>> queue.pop(0)
'Eric'
>>> queue.pop(0)
'John'
>>> queue
['Michael', 'Terry', 'Graham']

1.2 函数化编程工具 

[更进一步学习函数式编程可以看我的另一篇文章:Python函数式编程学习心得以及:lambda, map, reduce, filter的学习]

对于链表来讲,有三个内置函数非常有用:filter(), map(), 和reduce()。 “filter(function, sequence)” 返回一个序列(sequence),包括了给定序列中所有调用function(item)后返回值 为true的元素。(如果可能的话,会返回相同的类型)。例如,以下程序可以计算部分素数:
>>> def f(x): return x % 2 != 0 and x % 3 != 0
...
    >>> filter(f, range(2, 25))
    [5, 7, 11, 13, 17, 19, 23]
“map(function, sequence)” 为每一个元素依次调用function(item) 并将返回值组成一个链表返回。例如,以下程 序计算立方:
>>> def cube(x): return x*x*x
...
    >>> map(cube, range(1, 11))
    [1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]
可以传入多个序列,函数也必须要有对应数量的参数,执行时会依次用各序列上对应的元素来调用函数(如果某些序列比其它的短,就用None来代替)。如果把None做为一个函数传入,则直接返回参数做为替代。组合这两种情况,我们会发现“map(None, list1, list2)”是把一对序列变成元素对序列的便捷方式。例如:
>>> seq = range(8)
    >>> def square(x): return x*x
    ...
    >>> map(None, seq, map(square, seq))
    [(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25), (6, 36), (7, 49)]
"reduce(func, sequence)" 返回一个单值,它是这样构造的:首先以序列的前两个元素调用函数,再以返回值 和第三个参数调用,依次执行下去。例如,以下程序计算1到10的整数之和:
>>> def add(x,y): return x+y
    ...
    >>> reduce(add, range(1, 11))
    55
如果序列中只有一个元素,就返回它,如果序列是空的,就抛出一个异常。可以传入第三个参数做为初始值。
如果序列是空的,就返回初始值,否则函数会先接收初始值和序列的第一个元素,然后是返回值和下一个元素,依此类推。例如:
>>> def sum(seq):
    ... def add(x,y): return x+y
    ... return reduce(add, seq, 0)
    ...
    >>> sum(range(1, 11))
    55
    >>> sum([])
    0
不要像示例中这样定义sum():因为合计数值是一个通用的需求,在新的2.3版中,提供了内置的sum(sequence) 函数。

1.4 链表推导式

链表推导式提供了一个创建链表的简单途径,无需使用map(), filter() 以及lambda。返回链表的定义通常要比创建这些链表更清晰。每一个链表推导式包括在一个for语句之后的表达式,零或多个for或if语句。返回值是由for或if子句之后的表达式得到的元素组成的链表。如果想要得到一个元组,必须要加上括号。
>>> freshfruit = [' banana', ' loganberry ', 'passion fruit ']
>>> [weapon.strip() for weapon in freshfruit]
['banana', 'loganberry', 'passion fruit']
>>> vec = [2, 4, 6]
>>> [3*x for x in vec]
[6, 12, 18]
>>> [3*x for x in vec if x > 3]
[12, 18]
>>> [3*x for x in vec if x < 2]
[]
>>> [[x,x**2] for x in vec]
[[2, 4], [4, 16], [6, 36]]
>>> [x, x**2 for x in vec] # error - parens required for tuples
File "", line 1, in ?
[x, x**2 for x in vec]
^
SyntaxError: invalid syntax
>>> [(x, x**2) for x in vec]
[(2, 4), (4, 16), (6, 36)]
>>> vec1 = [2, 4, 6]
>>> vec2 = [4, 3, -9]
>>> [x*y for x in vec1 for y in vec2]
[8, 6, -18, 16, 12, -36, 24, 18, -54]
>>> [x+y for x in vec1 for y in vec2]
[6, 5, -7, 8, 7, -5, 10, 9, -3]
>>> [vec1[i]*vec2[i] for i in range(len(vec1))]
[8, 12, -54]
为使链表推导式匹配for循环的行为,可以在推导之外保留循环变量:
>>> x = 100 # this gets overwritten
>>> [x**3 for x in range(5)]
[0, 1, 8, 27, 64]
>>> x # the final value for range(5)
4

1.5 del 语句

有一个方法可从链表中删除指定索引的元素:del语句。这个方法也可以从链表中删除切片(之前我们是把一个空链表赋给切片)。例如:
>>> a = [-1, 1, 66.6, 333, 333, 1234.5]
>>> del a[0]
>>> a
[1, 66.6, 333, 333, 1234.5]
>>> del a[2:4]
>>> a
[1, 66.6, 1234.5]
del 也可以用于删除整个变量:
>>> del a
此后再引用这个名字会发生错误(至少要到给它赋另一个值为止)。后面我们还会发现del的其它用法。

|  ----------------------------------------------------------------------

二、tuple方法详解!

Help on class tuple in module __builtin__:

tuple定义注意事项:【更新于:2014.05.22】

1、只有1个元素时,需加分号

>>> t = ("abc")
>>> t
'abc'
>>> t1 = ("abc",)
>>> t1
('abc',)
>>> print type(t), type(t1)
 

原因是:()既可以表示tuple,又可以是数学公式中的()!所以tuple定义时候记得最后加上, 永不出错!上面代码可以看得出来,显示的时候也是加了,的。

2、tuple不是真正意思上的不可变

在下列的dict里面会有解释。简单来说:tuple里面可以定义可变的元素list,dict。

>>> t = (11 ,"aa", [22, "bb"], {1:"a", 2: "b"},)
>>> t,type(t)
((11, 'aa', [22, 'bb'], {1: 'a', 2: 'b'}), )
>>> t[2].append(u"可变")
>>> t[3].update({3: "c"})
>>> t[3].pop(1)
'a'
>>> t
(11, 'aa', [22, 'bb', u'\xbf\xc9\xb1\xe4'], {2: 'b', 3: 'c'})
>>> 

解释:tuple“不可变”指的是里面的元素不可变,也就是元素指向不变。但指向的东西如上面代码里的第2个位置为list,list可变,所以看起来tuple是可变的。

要保证tuple里面所有东西都不变,则tuple里面的元素不能用可变的list等。

class tuple(object)

 |  tuple() -> empty tuple # 同list,工厂函数
 |  tuple(iterable) -> tuple initialized from iterable's items  # 同list
 |  
 |  If the argument is a tuple, the return value is the same object.
 |  
 |  Methods defined here:
 |  
 |  count(...)  # 同list
 |      T.count(value) -> integer -- return number of occurrences of value
 |  
 |  index(...)  # 同list
 |      T.index(value, [start, [stop]]) -> integer -- return first index of value.
 |      Raises ValueError if the value is not present.
 |  
 |  ----------------------------------------------------------------------

三、dict方法详解!

Help on class dict in module __builtin__:

class dict(object)
 |  dict() -> new empty dictionary   工厂函数
 |  dict(mapping) -> new dictionary initialized from a mapping object's
 |      (key, value) pairs
以下关于mapping object的解释来自于:点击打开链接
mapping object把一个可哈希的值(hashable value)映射到一个任意的object上。
什么是可哈希的:
一个object是可哈希的(hashable), 是指这个object在其生存期内有一个不变的哈希值(hash value),即__hash__()方法返回的值。
所有不可变的(immutable)内置object都是hashable的,比如string,不可变的tuple【2014.4.9修订:此处错误,因为tuple可以嵌套list和dict,本质上还是可变的!所以不是所有tulpe都可以作为key!作为key的要求是绝对不可变。所以我强调是不可变的tuple。所有可变的(mutable)内置容器不是hashable的,比如list,dict(即没有__hash__()方法)。而所有自定义的类(use-defined class)对象都是可哈希的hashable),并且只能和自己相等,其hashvalue为其id(object)的值,这里的id()为内置函数,CPython实现的时候取的对象在内存中的地址。
字典Dictionary的key必须是可哈希的,所以tuple,string可以做key,而list不能做key,关于这个我以后会专门解释,或参见https://wiki.python.org/moin/DictionaryKeys。
 |  dict(iterable) -> new dictionary initialized as if via:
 |      d = {}
 |      for k, v in iterable:
 |          d[k] = v
>>> for k, v in zip(range(10),range(10, 20)):
	print k, v

	
0 10
1 11
2 12
3 13
4 14
5 15
6 16
7 17
8 18
9 19
 |  dict(**kwargs) -> new dictionary initialized with the name=value pairs
 |      in the keyword argument list.  For example:  dict(one=1, two=2)
 |  
 |  Methods defined here:
 |  
 |  clear(...) # 删除所有items
 |      D.clear() -> None.  Remove all items from D.
 |  
 |  copy(...) # 浅复制,【2014.4.9修订:已有字典,建立同样新字典,copy()比dict()快】
 |      D.copy() -> a shallow copy of D
>>> x ={'username' : 'admin', 'machines' : ['foo', 'bar', 'baz']}
>>> y = x.copy()
>>> y
{'username': 'admin', 'machines': ['foo', 'bar', 'baz']}
>>> y["machines"].remove("foo")
>>> y
{'username': 'admin', 'machines': ['bar', 'baz']}
>>> x
{'username': 'admin', 'machines': ['bar', 'baz']}
>>> x["machines"].remove("baz")
>>> x
{'username': 'admin', 'machines': ['bar']}
>>> y
{'username': 'admin', 'machines': ['bar']}
>>> x.pop("username")
'admin'
>>> x
{'machines': ['bar']}
>>> y
{'username': 'admin', 'machines': ['bar']}
>>> y.update({"test": "hello"})
>>> y
{'username': 'admin', 'test': 'hello', 'machines': ['bar']}
>>> x
{'machines': ['bar']}
>>> x.update({"username": "world"})
>>> x
{'username': 'world', 'machines': ['bar']}
>>> y
{'username': 'admin', 'test': 'hello', 'machines': ['bar']}
也就是说字典里的浅复制,涉及到字典嵌套或者一个key多个value就要注意了!父对象的替换相互是没有影响的,但是涉及到嵌套或者key的值多个的话的话,会导致互相修改!
深浅复制请看下面!
copy(x)
        Shallow copy operation on arbitrary Python objects.
# 只拷贝父对象。
        
        See the module's __doc__ string for more info.
    
    deepcopy(x, memo=None, _nil=[])
        Deep copy operation on arbitrary Python objects.   # 复制所有深层对象,也就是说复制对象及其子对象。
        
        See the module's __doc__ string for more info.
>>> import copy
>>> x ={'username' : 'admin', 'machines' : ['foo', 'bar', 'baz']}
>>> y = copy.deepcopy(x)
>>> x["machines"].remove("baz")
>>> x
{'username': 'admin', 'machines': ['foo', 'bar']}
>>> y
{'username': 'admin', 'machines': ['foo', 'bar', 'baz']}
>>> y["machines"].remove("foo")
>>> y
{'username': 'admin', 'machines': ['bar', 'baz']}
>>> x
{'username': 'admin', 'machines': ['foo', 'bar']}
注意copy中的深浅复制不同之处!
也就是说深复制所有都有东西都是全新的,不再相互关联。

 |  fromkeys(...)   # 具体看例子。也可以使用给定的key建立字典,默认为None,也可以自己赋值。
 |      dict.fromkeys(S[,v]) -> New dict with keys from S and values equal to v.
 |      v defaults to None.
>>> x ={'username' : 'admin', 'machines' : ['foo', 'bar', 'baz']}
>>> y ={}
>>> y.fromkeys(x, "unknow")
{'username': 'unknow', 'machines': 'unknow'}
>>> y
{}
>>> y = y.fromkeys(x, "unknow")
>>> y
{'username': 'unknow', 'machines': 'unknow'}
>>> y = y.fromkeys(x)
>>> y
{'username': None, 'machines': None}
>>> z = {}
>>> z = z.fromkeys(range(10), "test")
>>> z
{0: 'test', 1: 'test', 2: 'test', 3: 'test', 4: 'test', 5: 'test', 6: 'test', 7: 'test', 8: 'test', 9: 'test'}
# 实测赋值只能是一个值!所有key的值都相同。
 
   这个设计感觉很怪,你说y.fromkeys(x)生成的dict不会给y,是不是很怪? 
   
 
   
 
   
 
   
 
   
 
   
 
   
 
  
 |  get(...)   # 访问字典键key的值,如果有返回value,没有则返回None或者自定义返回为d!
 |      D.get(k[,d]) -> D[k] if k in D, else d.  d defaults to None.
>>> x ={'username' : 'admin', 'machines' : ['foo', 'bar', 'baz']}
>>> x.get("machines")
['foo', 'bar', 'baz']
>>> x.get("test")
>>> x.get("test", "this is a test")
'this is a test'
 |  has_key(...) # 检查字典是否有k这个key,有返回True,没有返回False!非常有用!== k in D 【2014.4.9修订:推荐使用in or not in】
 |      D.has_key(k) -> True if D has a key k, else False
 |  
 |  items(...) items方法将所有的字典项以列表的方式返回,列表中的项由(key,value)组成,返回项无特殊顺序。
 |      D.items() -> list of D's (key, value) pairs, as 2-tuples
 |  
 |  iteritems(...) # 返回一个迭代对象!
 |      D.iteritems() -> an iterator over the (key, value) items of D
>>> x = {'username' : 'admin', 'machines' : ['foo', 'bar', 'baz'], "hello": "world"}
>>> x.items()
[('username', 'admin'), ('hello', 'world'), ('machines', ['foo', 'bar', 'baz'])]
>>> x.iteritems()

>>> list(x.iteritems())
[('username', 'admin'), ('hello', 'world'), ('machines', ['foo', 'bar', 'baz'])]
 |  iterkeys(...) # 返回keys的迭代器
 |      D.iterkeys() -> an iterator over the keys of D
 |  
 |  itervalues(...) # 返回values的迭代器
 |      D.itervalues() -> an iterator over the values of D
 |  
 |  keys(...) # 以list的形式返回D的键
 |      D.keys() -> list of D's keys
 |  
 |  pop(...) # 将给定key的value移除字典,并返回这个value。如果没有,则返回指定的值d,没有指定话,抛出异常!
 |      D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
 |      If key is not found, d is returned if given, otherwise KeyError is raised
 |  
 |  popitem(...) # 同上,只不过是键值对,是随机的!dict没有顺序的概念。
 |      D.popitem() -> (k, v), remove and return some (key, value) pair as a
 |      2-tuple; but raise KeyError if D is empty.
 |  
 |  setdefault(...) 类似get方法,能够返回给定key的value,此外setdefault还能在不含有给定key的情况下设定相应的key-value为d。
 |      D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D
 |  
 |  update(...) # 更新字典,()里面必须为dict,也就是需用一个字典更新这个字典D,如果key在D中则更新为新的,如果key不在D里面,添加进D!
 |      D.update([E, ]**F) -> None.  Update D from dict/iterable E and F.
 |      If E present and has a .keys() method, does:     for k in E: D[k] = E[k]
 |      If E present and lacks .keys() method, does:     for (k, v) in E: D[k] = v
 |      In either case, this is followed by: for k in F: D[k] = F[k]
>>> x
{'username': 'admin', 'test': 'this is a test', 'hello': 'world', 'machines': ['foo', 'bar', 'baz']}
>>> x.update({"test": "changed"})
>>> x
{'username': 'admin', 'test': 'changed', 'hello': 'world', 'machines': ['foo', 'bar', 'baz']}
 |  values(...) # 以list的形式返回所有value,list意味着可以返回重复的value
 |      D.values() -> list of D's values
 |  
 |  viewitems(...) 
 |      D.viewitems() -> a set-like object providing a view on D's items
 |  
 |  viewkeys(...)
 |      D.viewkeys() -> a set-like object providing a view on D's keys
 |  
 |  viewvalues(...)
 |      D.viewvalues() -> an object providing a view on D's values
>>> x.viewkeys()
dict_keys(['username', 'test', 'hello', 'machines'])
>>> x.viewvalues()
dict_values(['admin', 'changed', 'world', ['foo', 'bar', 'baz']])
>>> d.viewitems()
dict_items([(1, 'gg'), (2, 'b'), (3, 'c'), (4, {1: 'a', 2: 'b', 3: 'mm'})])
| 【2014.4.9修订:内置sorted对keys()排序!】
|  ----------------------------------------------------------------------
【2014.05.22更新】

和list比较,dict有以下几个特点:

  1. 查找和插入的速度极快,不会随着key的增加而增加;
  2. 需要占用大量的内存,内存浪费多。

而list相反:

  1. 查找和插入的时间随着元素的增加而增加;
  2. 占用空间小,浪费内存很少。

dict是用空间来换取时间的一种方法。


反转字典的方法:
1.dict((v, k) for k, v in d.iteritems())
2.dict(zip(d.itervalues(), d.iterkeys()))
注:反转字典肯定不能破坏字典的规则,也就是key绝对不可能为可变的,例如list,dict对象!只能为不可变的str,tuple对象!
>>> d = {1: "a", 2: "b", 3: "c"}
>>> d
{1: 'a', 2: 'b', 3: 'c'}
>>> dict((v, k) for k, v in d.iteritems())
{'a': 1, 'c': 3, 'b': 2}
>>> dict(zip(d.itervalues(), d.iterkeys()))
{'a': 1, 'c': 3, 'b': 2}


请尊重作者的劳动成果,转载请带上本文地址:http://blog.csdn.net/zhanh1218/article/details/21864531不定期更新。

本文由@The_Third_Wave原创。不定期更新,有错误请指正。

Sina微博关注:@The_Third_Wave 

如果这篇博文对您有帮助,为了好的网络环境,不建议转载,建议收藏!如果您一定要转载,请带上后缀和本文地址。

你可能感兴趣的:(Python)