Python数据分析(一)

 

元组

元组是一种固定长度、不可变的Python对象序列。

tup = 4, 5, 6
tup
nested_tup = (4, 5, 6), (7, 8)
nested_tup

你可以使用tuple函数将任意序列或迭代器转换为元组:

tuple([4, 0, 2])
tup = tuple('string')
tup

元组的元素可以通过中括号[]来获取

tup[0]

虽然对象元组中存储的对象其自身是可变的,但是元组一旦创建,各个位置上的对象是无法被修改的:

tup = tuple(['foo', [1, 2], True])
tup[2] = False

如果元组中的一个对象是可变的,例如列表,你可以在它内部进行修改:

tup[1].append(3)
tup

可以使用+号连接元组来生成更长的元组:

(4, None, 'foo') + (6, 0) + ('bar',)
('foo', 'bar') * 4

元组拆包

tup = 4, 5, (6, 7)
a, b, (c, d) = tup
d
seq = [(1, 2, 3), (4, 5, 6), (7, 8, 9)]
for a, b, c in seq:
    print('a={0}, b={1}, c={2}'.format(a, b,c))
values = 1, 2, 3, 4, 5
a, b, *rest = values
rest

列表

与元组不同,列表的长度是可变的,它所包含的内容也是可以修改的。

a_list = [2, 3, 7, None]
a_list
tup = ('foo', 'bar', 'baz')
b_list = list(tup)
b_list
list(range(10))

增加和移除元素

b_list.append('dwarf')
b_list
b_list.insert(1, 'red')
b_list
b_list.pop(2)
b_list.append('foo')
b_list.remove('foo')
b_list

使用in关键字可以检查一个值是否在列表中,not关键字可以用作in的反义词,表示“不在”。检查列表中是否包含一个值是非常缓慢的。这是因为Python在列表中进行了线性逐个扫描,而在字典和集合中Python是同时检查所有元素的(基于哈希表)。

'foo' in b_list
'foo' not in b_list

连接和联合列表

# 代价较高
[4, None, 'foo'] + [7, 8, (2, 3)]
# 推荐使用extend
x = [4, None, 'foo']
x.extend([7, 8, (2, 3)])
x

排序

a = [7, 2, 5, 1, 3]
a.sort()
a
b = ['saw', 'small', 'He', 'foxes', 'six']
b.sort(key=len)
b

查找和插值

内建的bisect模块实现了二分搜索和已排序列表的插值。bisect.bisect会找到元素应当被插入的位置,并保持序列排序,而bisect.insort将元素插入到相应位置:bisect模块的函数并不会检查列表是否已经排序,因为这么做代价太大。

import bisect
c = [1, 2, 2, 2, 3, 4, 7]
bisect.bisect(c, 2)
bisect.insort(c, 5)
c

列表、集合和字典推导式

列表推导式是允许你过滤一个容器的元素,用一种简明的表达式转换传递给过滤器的元素,从而生成一个新的列表。推导式与for循环是等价的。

result = []
for val in collection:
    if condition:
        result.append(expr)

列表推导式

strings = ['a', 'as', 'bat', 'car', 'dove', 'python']
[x.upper() for x in strings if len(x) > 2]

字典推导式

loc_mapping = {val : index for index, val in enumerate(strings)}
loc_mapping

集合推导式

unique_lengths = {len(x) for x in strings}
unique_lengths
# 更简洁的写法
# set(map(len, strings))

嵌套列表推导式

获得一个列表包含所有含有2个以上字母e的名字,使用for循环:

all_data = [['John', 'Emily', 'Michael', 'Mary', 'Steven'],['Maria', 'Juan', 'Javier', 'Natalia', 'Pilar']]
names_of_interest = []
for names in all_data:
    enough_es = [name for name in names if name.count('e') >= 2]
    names_of_interest.extend(enough_es)
names_of_interest

用列表推导式:列表推导式的for循环部分是根据嵌套的顺序排列的,所有的过滤条件像之前一样被放在尾部。

result = [name for names in all_data for name in names if name.count('e') >= 2]
result
some_tuples = [(1, 2, 3), (4, 5, 6), (7, 8, 9)]
flattened = [x for tup in some_tuples for x in tup]
flattened

柯里化

柯里化是计算机科学术语(以数学家Haskell Curry命名),它表示通过部分参数应用的方式从已有的函数中衍生出新的函数。

def add_numbers(x, y):
    return x + y
# 第二个参数对于函数add_numers就是柯里化了。
add_five = lambda y: add_numbers(5, y)
# partial函数简化
from functools import partial
add_five = partial(add_numbers, 5)