一些简单概念:
字面常量,也就是我们所说的常量,在计算机中也就是一块内存。
变量:指向内存的一对符号。
文件系统:决定了文件的存放方式。
按位与: &
按位或: |
异或: ^
列表:
列表:列表的复制为引用赋值,为浅拷贝,重新复制的时候id值是相同的,两者会同时修改,如果需要独立复制,则需要用切片方法来复制,为深度拷贝。列表相当于其他语言中的数组。
1、列表的基本概念:
>>> f = [1, 2, 3, 9, 5] ###定义一个列表
>>> len(f) ###取列表的长度
5
>>> max(f) ###取列表的最大值
9
>>> min(f) ###取最小值
1
>>> 2 in f ###判断一个字符是否在列表中
True
>>> del f[0] ###删除列表中的一个元素,按照列表的下标来删除
>>> f
[2, 3, 9, 5]
2、列表的基本操作
>>> l=[1,2,3,4]
>>> l
[1, 2, 3, 4]
>>> l.append(‘a‘) ###在列表后面追加一个元素
>>> l
[1, 2, 3, 4, ‘a‘]
>>> l.append([1,2,3]) ###在列表后面追加一个列表
>>> l
[1, 2, 3, 4, ‘a‘, [1, 2, 3]]
>>> l.extend([‘a‘,‘b‘,1,2,3]) ###将这个列表扩展到原来的列表中,并且打散
>>> l
[1, 2, 3, 4, ‘a‘, [1, 2, 3], ‘a‘, ‘b‘, 1, 2, 3]
>>> f=[‘hello‘,‘world‘]
>>> f.extend(l) ###将l列表扩展到f列表中
>>> f
[‘hello‘, ‘world‘, 1, 2, 3, 4, ‘a‘, [1, 2, 3], ‘a‘, ‘b‘, 1, 2, 3]
>>> l=[1,2,3,4]
>>> l.insert(1,100) ###将100插入到下标为1的前面
>>> l
[1, 100, 2, 3, 4]
>>> l.insert(len(l),1000) ###将1000插入末尾
>>> l
[1, 100, 2, 3, 4, 1000]
>>> l.insert(1,[1,2,3,4]) ###在列表的下标为1的前面插入一个新的列表
>>> l
[1, [1, 2, 3, 4], 100, 2, 3, 4, 1000]
>>> l.remove(1000) ###从左向右删除这个值,一次只能删除一个
>>> l
[1, [1, 2, 3, 4], 100, 2, 3, 4]
>>> l.pop() ###从列表中最后的一个值先返回再删除,pop中加参数,代表删除下标对应的数值
4
>>> l
[1, [1, 2, 3, 4], 100, 2, 3]
>>> l
[1, [1, 2, 3, 4], 100, 2, 3]
>>> l.count(1) ###在列表中计算1出现的次数
1
[1, [1, 2, 3, 4], 100, 2, 3]
>>> l.index(1) ###在列表中查找1所在的下标
0
>>> l.index(3)
4
>>> dir(l) ###查看l这个列表的变量
[‘__add__‘, ‘__class__‘, ‘__contains__‘, ‘__delattr__‘, ‘__delitem__‘, ‘__delslice__‘, ‘__doc__‘, ‘__eq__‘, ‘__format__‘, ‘__ge__‘, ‘__getattribute__‘, ‘__getitem__‘, ‘__getslice__‘, ‘__gt__‘, ‘__hash__‘, ‘__iadd__‘, ‘__imul__‘, ‘__init__‘, ‘__iter__‘, ‘__le__‘, ‘__len__‘, ‘__lt__‘, ‘__mul__‘, ‘__ne__‘, ‘__new__‘, ‘__reduce__‘, ‘__reduce_ex__‘, ‘__repr__‘, ‘__reversed__‘, ‘__rmul__‘, ‘__setattr__‘, ‘__setitem__‘, ‘__setslice__‘, ‘__sizeof__‘, ‘__str__‘, ‘__subclasshook__‘, ‘append‘, ‘count‘, ‘extend‘, ‘index‘, ‘insert‘, ‘pop‘, ‘remove‘, ‘reverse‘, ‘sort‘]
>>> l.reverse() ###反向输出列表
>>> l
[‘b‘, ‘a‘, 5, 4, 3, 2, 1, 3, [1, 2, 3, 4], 5, 3, 4, 3, 2, 1]
>>> l.sort() ###对列表进行排序
>>> l
[1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, [1, 2, 3, 4], ‘a‘, ‘b‘]
###########注意###########
>>> p
[1, 2, 6, 7, 8, 9, 9, 32, 43, 43, 90]
>>> d=p
>>> d
[1, 2, 6, 7, 8, 9, 9, 32, 43, 43, 90]
>>> d=p.sort()
>>> d
>>> type(d) ###此时的d为空,因为p.sort()函数无返回值,所以返回为空,所以d列表中为空
<type ‘NoneType‘>
#########################
>>> l.insert(l.index(3),10) ###在一个值的前面插入一个元素
>>> l
[1, 2, 10, 3, 4, 5]
>>> l.insert(l.index(3)+1,10) ###在一个值的后面插入一个元素
>>> l
[1, 2, 10, 3, 10, 4, 5]
切片:将列表中特定区间中的值输出 例如: list[1:10:1] ###起始点:结束点:步长
Python中直接拷贝,两个标签指向的内存在同一个位置,使用切片复制时,属于两个不同的内存
>>> k = l ###直接拷贝
>>> l
[1, 2, 10, 3, 10, 4, 5]
>>> k
[1, 2, 10, 3, 10, 4, 5]
>>> id(k) ###内存id号和原来的列表id号一致
42219640
>>> k = l[::] ###不加起点、终点、步长,代表从列表的第一位输出到列表的最后一位
>>> k
[1, 2, 10, 3, 10, 4, 5]
>>> l
[1, 2, 10, 3, 10, 4, 5]
>>> id(k) ###使用切片后,id号会变化
42222872
>>> id(l)
42219640
>>> l
[1, 2, 10, 3, 10, 4, 5]
>>> w = tuple(l) ###将一个列表直接转换成元组
>>> w
(1, 2, 10, 3, 10, 4, 5)
列表解析:将列表中的数据进行循环运算,性能远远高于for循环
>>> li = [1,2,3]
>>> li2 = [i+1 for i in li] ###将li列表中的每个元素+1,注意,表达式只能有一个,可以写成无
>>> li2
[2, 3, 4]
>>> for i in li: ###上面的列表解析相当于这个for循环,但是效率比for循环的效率高
... li3.append(i+1)
...
>>> li3
[2, 3, 4]
列表解析和元组解析的区别:
>>> li = [1,2,3,4]
>>> li2 = [i+1 for i in li] ###列表解析,直接通过for循环生成目标列表
>>> li2
[2, 3, 4, 5]
>>> li2 = (i+1 for i in li) ###元组解析,生成一个迭代器,每次需要的结果需要使用li2.next输出
>>> li2
<generator object <genexpr> at 0x27b8f00>
>>> type(li2)
<type ‘generator‘>
>>> li2.next() ###主动的输出元组中的值,
2
>>> li2.next()
3
>>> li2.next()
4
>>> li2.next()
5
>>> li2.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration ###此处stop
带条件的列表解析:就是在列表解析中加入另外的条件
>>> li3 = [i+1 for i in li if i %2 == 0] ###将li列表中的偶数元素+1
>>> li3
[3]
>>> id(li3) ###每个列表的id都不同
42219856
>>> id(li)
42219640
>>> li4 = [i for i in li if i % 2 == 0 if i > 5] ###if条件可以写多个,用多个条件对列表进行限制
>>> li4
[6, 8]
两个列表的笛卡尔积:
>>> li4 = [(i,x) for i in li for x in li1] ###由于表达式只能有一个,所以用一个元组存放
>>> li4
[(1, 4), (1, 5), (1, 6), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), (3, 6)]
迭代器的性能远高于列表解析
元组:
元组:元组中的值不可更改,但是,在元组中加入列表的时候,此时列表中的值可修改
如果通过完全切片来复制,则两个元组的id号一致
集合:
集合:集合中的数据是无序排列的,并且是唯一的,并且会自动将hash值一致的数据进行合并,只有支持hash的数据才可放入集合中,集合不支持切片,声明一个空的集合:s = set()
>>> s = {} ###默认定义为一个空字典
>>> type(s)
<type ‘dict‘>
>>> s = set() ###定义一个空集合
>>> type(s)
<type ‘set‘>
>>> s = {1,2,3,1,1,1,‘1‘} ###定义一个集合
>>> s
set([‘1‘, 1, 2, 3]) ###定义集合时,重复的符号只取其中一个
>>> s = {1,2,3,1,1,1,‘1‘,[1,2,3]} ###列表不可被hash,所以不能加入集合
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: ‘list‘
>>> s = list(set([1,2,1,2,1,2,1,2])) ###可以使用集合对列表进行去重
>>> s
[1, 2]
>>> s
set([1, 2, 3, 4])
>>> s.add(100) ###在集合中加入一个值,无序排列
>>> s
set([1, 2, 3, 4, 100])
>>> s.update([200,300]) ###将一个列表更新到集合中,注意,不是加入
>>> s
set([1, 2, 3, 4, 200, 300, 100])
>>> s.remove(100) ###删除集合中的一个值
>>> s
set([1, 2, 3, 4, 200, 300])
>>> s.pop() ###随即删除集合中的一个值
1
>>> s
set([2, 3, 4, 200, 300])
>>> s.discard(‘a‘) ###先在集合中查找这个值,如果没有,不做删除,否则删除
>>> s
set([2, 3, 4, 200, 300])
>>> s1 = {1,2,3}
>>> type(s1)
<type ‘set‘>
集合中的运算:
>>> s1.difference(s) ###取s1对s的差集
set([1])
>>> s.difference(s1) ###取s对s1的差集
set([200, 300, 4])
>>> s.difference_update(s1) ###求出差集后修改原值
>>> s
set([1, 5])
>>> s - s1 ###做减运算,相当于差集
set([200, 300, 4])
>>> s1 - s
set([1])
>>> s
set([2, 3, 4, 200, 300])
>>> s1
set([1, 2, 3])
>>> s.intersection(s1) ###交集
set([2, 3])
>>> s1.intersection(s)
set([2, 3])
set([1, 2, 3, 4, 5])
>>> s1
set([2, 3, 4])
>>> s.issubset(s1) ###子集,如果s1是s的子集,则返回True
False
>>> s1.issubset(s)
True
>>> s1.isdisjoint(s) ###如果两个集合没有共同的元素,则返回True,返回False,相当于intersection的负集
>>> s2.clear() ###清空一个集合
>>> s2.issuperset(s1) ###相当于issubset的负集
True
>>> s1
set([2, 3, 4])
>>> s2
set([1, 2, 3, 4, 5])
>>> s
set([1, 2, 4])
字典:
字典:{key:value},不能有重复的key,也就是说,key必须可hash,元组可作为key,列表不可以做为key,集合也不可用作key,迭代器的循环效率高于普通循环,字典不支持切片操作,但是支持copy
>>> d.keys() ###以列表的形式返回key
[‘age‘, ‘name‘, ‘sex‘]
>>> d.values() ###以列表的形式返回values
[23, ‘tom‘, ‘male‘]
>>> it = d.iterkeys() ###将字典中的key值定义为迭代器
>>> type(it)
<type ‘dictionary-keyiterator‘>
>>> it.next() ###主动请求迭代器中的数值
‘age‘
>>> it.next()
‘name‘
>>> it.next()
‘sex‘
>>> it.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> d.items() ###将字典中的key:values用元组的形式成对输出
[(‘age‘, 23), (‘name‘, ‘tom‘), (‘sex‘, ‘male‘)]
>>> d.items()
[(‘age‘, 23), (‘name‘, ‘tom‘), (‘sex‘, ‘male‘)]
>>> for i in d.values(): ###输出values
... print i
...
23
tom
male
>>> for i in d.keys(): ###输出keys
... print i,d[i]
...
age 23
name tom
sex male
>>> d.get(‘name‘) ###获取字典中key所对应的value
‘tom‘
>>> d.get(‘eat‘,1111) ###获取字典中的key值时如果没有这个key值,则返回一个随机值
1111
>>> d[‘name‘]
‘tom‘
>>> d.has_key(‘name‘) ###可以用来判断key值是否存在
True
>>> d[‘phone‘] = 1111111 ###在字典中添加一个值,如果这个值已经存在,则进行修改
>>> d
{‘phone‘: 1111111, ‘age‘: 23, ‘name‘: ‘tom‘, ‘sex‘: ‘male‘}
#################函数##################
函数定义:def func_name():
print ‘hello’
func_name() ###调用函数
变量:局部变量: 定义在函数内的变量,只能被函数本身调用,该变量为局部变量,当函数需要使用全局变量时,需要使用global 来调用全局变量,函数中存在一种延迟绑定
全局变量:定义在函数外部的变量,可以在全局中被调用
当函数名相同时,局部变量的优先级高于全局变量
1 #!/usr/bin/env python ###在linux系统中,该行为指定python的运行目录
2 #coding=utf-8 ###改行为指定使用字符集
3
4 def func_name(arg,arg1,arg2,arg3): #形式参数,作为局部变量
5 print arg,arg1,arg2,arg3
6
7 func_name(100,99,98,97) #实际参数,位置传参
8 func_name(arg3 =100,arg2 = 99,arg1 = 98,arg = 97) #关键字传参
9
10 def func_name1(arg1,arg2,arg3,arg=100): #带默认值的形式参数一定要定义在所有
不带默认值参数的后面
11 print arg,arg1,arg2,arg3
12 func_name1(2,3,4)
可变参数:(数量不一定),当参数传进来后,默认为一个元组,可以解决函数参数不够用的情况
1 #!/usr/bin/env python
2 #coding=utf8
3 def func_name(*arg): #可变参数传参
4 #arg is a tuple
5 print arg #参数的打包
6
7 li = [3,4,5,6,7]
8 func_name(*li) #相当于func_name(3,4,5,6,7)
9
10 li2 = [‘a‘]
11
12 func_name(*li2) #参数的解包
13
14 func_name(1,2)
15 #([3,4,5,6,7])
例题:
1 #!/usr/bin/env python
2 #coding=utf8
3
4 def func_name(*arg):
5 host = arg[0]
6 port = arg[1]
7 username = arg[2]
8 passwd = arg[3]
9 db = None
10 if len(arg) == 5:
11 db = arg[4]
12 # if db is None default db is test
13 # if db is not None
14
15 func_name(‘127.0.0.1‘,3306,‘root‘,‘123456‘)
可变位置传参:
关键字传参:和参数传递的顺序无关,但是在传参的时候必须指定好参数的位置.
1 #!/usr/bin/env python
2 #coding=utf8
3
4 def func_name(**kwarg): #可变位置参数
5 print kwarg
6 print kwarg[‘port‘]
7 if kwarg.has_key(‘db‘):
8 pass
9 else:
10 print ‘db is not have‘
11 #kwarg is a dict
12
13 func_name(host=‘127.0.0.1‘,port=3306,username=‘root‘)
Python中所有的函数都是有返回值的,如果没有指定返回值,则默认返回值为None,可以返回多个值(相当于返回一个元组),但是如果只有一个变量接收时,则该变量则接收一个元组。
#!/usr/bin/env python
def func_re(x,y):
return x+y,x*y
b = func_re(1,3) ###此时一个变量接收两个返回值
a = list(func_re(1,3)) ###将返回值转换为一个列表
print a,b
[4,3] (4, 3) ###输出为一个列表和元组
函数中尽量不要使用print,保持函数的纯洁性,不然会产生副作用,调试时可以加入print来调用
##################递归算法#####################
Python中最大的递归层数为999层,第1000层就会报错
1 #!/usr/bin/env python
2 #coding=utf8
3 #递归函数
4 #递归算法
5 def func_mul(n):
6 if n<=1:
7 return n
8 return func_mul(n-1)*n
###列表迭代算法
9 def func_mul2(n):
10 ret = 1
11 for x in range(n,1,-1):
12 ret = ret * x
13 return ret
14 a = func_mul(999)
15 print a
16 b = func_mul2(10)
17 print b
################函数传参#################
在定义函数时,可以将函数作为一个参数来进行重新定义,并且可以重新调用
1 #!/usr/bin/env python
2 #coding=utf8
3
4 def func_name():
5 return ‘test‘
6
7 func = func_name #相当于将函数赋值给了func参数,两者的id时一致的,func可以> 调用函数
8 func1 = func_name() #相当于将函数的返回值赋值给func1
9
10 print func() #直接调用函数,可以返回‘test‘
11 print func1
12 def func(f):
13 print ‘call func‘
14 f(1,2)
15
16 def func2(x,y):
17 print ‘call func2\n‘,x+y
18
19 func(func2)
输出结果:
test
test
call func
call func2
3
##########高阶函数############
filter():filter(func,list) 过滤函数
>>> li
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> def f1(x):
... return x % 2 == 0 ###相当于将列表中的偶数过滤出来
...
>>> filter(f1,li)
[2, 4, 6, 8]
map() : map(func,list) 将列表中的所有元素都放在一个函数中执行一次,适用于hadoop,bigdata
如果一个服务器内存为8G,现在在一个10G大小的日志文件中查找出前10的IP
首先:需要将这个文件切割,由于文件太大,台占用内存,甚至于打不开该文件;比如切割成20份文件,先找到每份中前10,在将所以的前10放在一个文件中,然后再找前10
map ---->reduce MR 先分再总结,在进行切片的时候,可以使用awk命令
>>> li
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> def f2(x):
... return x*2
...
>>> map(f2,li) ###相当于对列表整体相乘2,扩大了一倍
[2, 4, 6, 8, 10, 12, 14, 16, 18]
reduce() : reduce(func,list) 将列表中的前两个元素相操作的结果和第三个元素进行操作,再将操作结果与第四个元素进行操作,相当于进行一次阶乘,相当于一个总结的过程,报告生成器
>>> li
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> def f3(x,y):
... return x*y
...
>>> reduce(f3,li) ###相当于对列表进行了一次阶乘
362880
若想知后事如何,请继续关注……