list¶
PyListObject in python2¶
class list in python3¶
class list([iterable])
初始化¶
- 初始化一个长度为N的list object
下面的代码示范的3种初始化list object的方法中,2种对的,1种错误。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #1.用列表推导式初始化
>>> lt = [None for i in range(5)]
>>> lt
[None, None, None, None, None]
>>> len(lt)
5
#2.Using the type constructor
>>> lt = list(range(5))
>>> lt
[0, 1, 2, 3, 4]
#3.不可以直接指定list的长度
>>> lt = list(5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
|
排序¶
谈到list排序,肯定想到的就是class List的成员函数list.sort(cmp=None, key=None, reverse=False),但是有一个隐含的至关重要的概念”sorting key”被忽视了,sort()真正上是依据list items对应的”sorting key”来对items排序的。
- 默认情况下,list中每个item的值是”sorting key”
1 2 3 4 5 6 7 8 | # vowels list
vowels = ['e', 'a', 'u', 'o', 'i']
# sort the vowels
vowels.sort()
# print vowels
print('Sorted list:', vowels) #Sorted list: ['a', 'e', 'i', 'o', 'u']
|
- 如果想自定义”sorting key”,就要用到sort()中的key参数了,显然key参数的值肯定是一个函数,但是对这个函数有一些要求——key parameter to specify a function
- to be called on each list element prior to making comparisons.
- takes a single argument and returns a key to use for sorting purposes. 这个返回的key是“可比较的”就行,不一定是一个数值,例如list, tuple都行,但是dict不行。
1 2 3 4 5 6 7 8 9 10 11 12 13 | # take second element for sort
def takeSecond(elem):
return elem[1]
# random list
random = [(2, 2), (3, 4), (4, 1), (1, 3)]
# sort list with key
random.sort(key=takeSecond)
# print list
print('Sorted list:', random)
#Sorted list: [(4, 1), (2, 2), (1, 3), (3, 4)]
|
优先级排序¶
有一份列表,其中的元素都是数字,要对其排序,排序时,要把出现在某个群组内的数字,放在群组外的那些数字之前。——言下之意,排序分为2个优先级(阶段),首先把属于某个群组中的数字放在列表前面,然后对前后两个部分分别排序。解决办法就是“使list item对应的sorting key带上prority信息”。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | numbers = [8, 3, 1, 2, 5, 4, 7, 6]
group = {2, 3, 5, 7}
def sortp(numbers, group):
#把list item对应的sorting key扩充成(1, item) or (0, item)
#元组的比较规则:首先比较下标为0的对应元素,如果相等,再比较下标为1的对应元素
def helper(x):
if x in group:
return (0, x)
else:
return (1, x)
numbers.sort(key=helper)
#注意,并没有return numbers
sortp(numbers, group)
print(numbers)
|
访问单个元素而不产生异常¶
访问列表中单个元素时,下标越界,会导致异常,IndexError: list index out of range
然而,切割列表时,即便start和end索引越界也不会出问题,只是返回空列表,[]
列表切割¶
- 列表切割在复制语句的右侧,会生成新的list object。所谓“全新的列表”,按照《python源码剖析》中p64“代码清单4-1”对创建PyListObject的2步过程的解释,就是ob_item指向了新建的“元素指针列表”。
1 2 3 4 5 6 7 | a = [1,2,3,4,5]
b = a[1:] //[2,3,4,5]
>>> b[0] = 7
>>> b
[7, 3, 4, 5]
>>> a
[1, 2, 3, 4, 5]
|
- 列表切割在赋值语句的左侧,就是replace的操作,如果赋值语句右侧的list的长度“小于”左侧,还有remove的操作。参考《python源码》p72 list_ass_slice()函数的解释
1 2 3 4 5 6 | >>> c
[10, 'a', 'b', 'c', 'd', 4, 5]
#['b', 'c', 'd']换成了['f','g']
>>> c[2:5] = ['f','g']
>>> c
[10, 'a', 'f', 'g', 4, 5]
|
列表复制¶
- 没有新建列表的复制
1 2 3 4 5 6 7 8 9 10 | >>> a
[1, 2, 3, 4, 5]
>>> c = a //c和a是同一个列表
>>> c
[1, 2, 3, 4, 5]
>>> c[0] = 9
>>> c
[9, 2, 3, 4, 5]
>>> a
[9, 2, 3, 4, 5]
|
- 新建了列表的复制
1 2 3 4 5 6 7 8 9 10 11 | >>> a
[9, 2, 3, 4, 5]
#列表切割在赋值语句的右侧的意义见上一小节
>>> d = a[:]
>>> d
[9, 2, 3, 4, 5]
>>> d[0] = 1
>>> d
[1, 2, 3, 4, 5]
>>> a
[9, 2, 3, 4, 5]
|
列表推导式¶
根据一份列表来制作另一份列表时,就用“列表推导式”。
- 用[]包围的comprehension生成的是一个真正的list,
- 用()包围的comprehension是一个generator object,而不是一个tuple。
1 2 3 4 5 6 7 | >>> a
[10, 'a', 'f', 'g', 4, 5]
>>> tu = (x for x in a)
>>> tu
<generator object <genexpr> at 0x0000000002B86C50>
>>> type(tu)
<class 'generator'>
|
- 用{}包围的comprehension生成的是一个dict object
高级用法¶
参考了<effective python>8th
- 使用2个条件,默认形成and
- 2个循环, 多用于2维列表.但是如果是3维或者以上,请使用for语句
- 列表推导式可生成多维列表
- 循环可以搭配自己的条件来使用