文档章节

杂记5:Python官网的The Python Tutorial笔记

fzyz_sb
 fzyz_sb
发布于 2015/06/13 08:32
字数 3036
阅读 258
收藏 0
点赞 0
评论 0

1. Python中列表赋值的问题

    在看官网时候,我个人写了如下的代码练习切割操作:

In[68]: letters
Out[68]: ['a', 'b', 'C', 'D', 'E', 'f', 'g']
In[69]: letters[2:5] = ['c', 'd', 'e']
In[70]: letters
Out[70]: ['a', 'b', 'c', 'd', 'e', 'f', 'g']
In[71]: letters[2:5] = ('C', 'D', 'E')
In[72]: letters
Out[72]: ['a', 'b', 'C', 'D', 'E', 'f', 'g']
    我当时的第一个疑问是:
In[71]: letters[2:5] = ('C', 'D', 'E')
In[72]: letters
Out[72]: ['a', 'b', 'C', 'D', 'E', 'f', 'g']
这里letters为什么不会被修改为:['a', 'b', ('C', 'D', 'E'), 'f', 'g' ].

    然后想明白了对于切割操作,外层的[]是语法糖,代表的里面包含的元素要替换letters中的列表,这时('C', 'D', 'E')实际上被解释为['C', 'D', 'E'],则上述的赋值操作,可以解释如下:

letters = ['a', 'b'] + ['c', 'd', 'e'] + ['f', 'g']
letters[2:5] = ('C', 'D', 'E') ==> ['a', 'b'] + ['C', 'D', 'E'] + ['f', 'g'] ==> ['a', 'b', 'c', 'd', 'e', 'f', 'g']
如果我们非要赋值元祖,可以提供一个列表,里面的数据是元祖即可:
In[74]: letters[2:5] = [('c', 'd', 'e')]
In[75]: letters
Out[75]: ['a', 'b', ('c', 'd', 'e'), 'f', 'g']
    这也解释了为什么我们清空列表可以这样编写:
In[76]: letters[:] = []
In[77]: letters
Out[77]: []


2. for循环的基本使用

    C++的STL支持迭代器,而Python中也直接类似的操作.例如我们遍历一个列表,通常有以下两种方法:

# -*- coding:utf-8 -*-
nums = range(0, 10)
#类似迭代器
for num in nums:
    print num,
print
#使用下标索引
for i in range(0, len(nums)):
    print nums[i],
print
    如果我们想要修改列表,通过索引则可以很简单实现:
#使用索引进行列表的修改
for i in range(0, len(nums)):
    nums[i] += 10
#[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
print nums
    而实际上通过迭代器无法实现,我们可以测试如下:
nums = [1, 2]
#[140520361897032, 140520361897008]
print [id(num) for num in nums]
#使用迭代实现修改元素
#140520361896792 140520361896768
for num in nums:
    num += 10
    print id(num),
print
#[1, 2]
print nums

     for循环中的每个num为数值,是不可改变的,所以每次执行+操作,会新建一个num,然后存储新值.这也是为什么这里的id会完全不同的原因.

    而且使用迭代器操作改变原列表有一个很隐藏的BUG!:

# -*- coding:utf-8 -*-
words = ['a', 'bb', 'ccc']
for w in words:
    print w
    if len(w) > 2:
        words.insert(0, w)

print words
这段代码会死循环直到内存溢出~_~

所以一般我们会修改成:

# -*- coding:utf-8 -*-
words = ['a', 'bb', 'ccc']
for w in words[:]:
    if len(w) > 2:
        words.insert(0, w)
#['ccc', 'a', 'bb', 'ccc']
print words

    for循环还有一个非常好用的属性:判断for循环是否完整运行:

# -*- coding:utf-8 -*-
nums = range(0, 3)
#类似迭代器
for num in nums:
    print num,
else:
    print '完整运行一遍'

for num in nums:
    if num > 1:
        break
else:
    print '这句话不会输出'
    
#输出如下: 0 1 2 完整运行一遍

    在循环中还有两个函数特别有用:enumerate和zip:

In[52]: for i, v in enumerate(['a', 'b', 'c']):
...     print i, v
...     
0 a
1 b
2 c
而zip可以将多个列表进行操作:
In[53]: for key, value in zip([0, 1, 2], ['a', 'b', 'c']):
...     print key, '=>', value
...     
0 => a
1 => b
2 => c


3. 函数的基本使用

    函数传参的基本原则是:传递一个对象,而非副本:

# -*- coding:utf-8 -*-
nums = [1, 2]
def func(nums):
    nums += [11, 12]

func(nums)
#[1, 2, 11, 12]
print nums
    函数名也只是一个对象,所以存在赋值操作:
# -*- coding:utf-8 -*-
def func():
    print 'hello world'

f = func
#hello world
f()
#4408107568
print id(f)
#4408107568
print id(func)
    函数传参时要遵循以下原则:

保证所传递的参数不被函数所修改,被修改的变量当做函数返回值,而非函数的参数.

例如:

# -*- coding:utf-8 -*-
def func(words, nums = []):
    newStr = words + ",".join(nums)
    return newStr

nums = ['1', '2']
newStr = func("hello", nums)
#['1', '2']
print nums
#hello1,2
print newStr
    我之前曾经思考过所传递的参数必须为元祖,例如传递参数时候将列表转换为元祖,在函数内部将元祖再转换为列表等,但是对于字典则很难办,而且代码会非常的繁琐.所以就按照上面的原则进行函数的编写.

    缺省参数的写法可以让我们完成类似C++的重载操作:

# -*- coding:utf-8 -*-
def func(words, nums = []):
    print words
    if nums:
        print nums

#hello
func('hello')
#hello
#[1, 2, 3]
func('hello', [1, 2, 3])


4. 列表的基本使用

1. 基本函数

list.append(x): 向后插入一个元素,等价于:a[len(a):] = [x]

list.extend(L): 通过插入列表L来达到扩展的目的,等价于a[len(a):] = L

list.insert(index, x): 在当前索引index前插入元素x

list.remove(x): 移除元素值等于x的元素.如果此元素不存在,则报错.

list.pop([i]): 移除指定索引的元素并返回删除元素的值.如果不带参数索引,则默认删除最后一个元素并返回它.

list.index(x): 返回值等于x的元素的索引,如果不存在则报错.

list.count(x): 返回x在列表中出现的次数

list.sort(cmp = None, key = None, reverse = False): 排序列表

list.reverse(): 反转列表

# -*- coding:utf-8 -*-
nums = [1, 2]
#[1, 2, 3]
nums.append(3)
#[1, 2, 3, 4, 5]
nums.extend([4, 5])
#[1, 1.11, 2, 3, 4, 5]
nums.insert(1, 1.11)
#[1, 2, 3, 4, 5]
nums.remove(1.11)
#3
print nums.pop(2)
#5
print nums.pop()
#2
print nums.index(4)
#1
print nums.count(1)
nums.reverse()
#[4, 2, 1]
print nums
2. 对列表有用的三个内建函数

filter(function, sequence): 对序列sequence中每个元素item执行function(item),返回为True组合的序列.除了str, unicode和tuple,其余的都返回列表

# -*- coding:utf-8 -*-
#[1, 3, 5, 7, 9]
print filter(lambda x: x % 2, range(0, 10))
#defg
print filter(lambda x: x > 'c', 'abcdefg')
#(4, 5)
print filter(lambda x: x > 3, tuple(range(0, 6)))
map(function, sequence): 与filter类似,但是function需要几个参数,则就需要几个序列
# -*- coding:utf-8 -*-
#[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
print map(lambda x: x * x, range(0, 10))
#[0, 2, 6, 12, 20, 30, 42, 56, 72, 90]
print map(lambda x, y: x * y, range(0, 10), range(1, 11))
reduce(function, sequence): 读取序列的前两个元素进行function,然后生成的结果作为第一个元素,和第三个元素继续组成两个元素,然后继续function.如果提供初始值,则以初始值作为第一个元素:
# -*- coding:utf-8 -*-
def add(x, y):
    return x + y
#55
print reduce(add, range(1, 11))

def mul(x, y):
    return x * y
#240
print reduce(mul, range(1, 5), 10)


5. 推导式的基本使用

    最常用的是列表推导式:

In[35]: [(x + 1) for x in range(0, 10)]
Out[35]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    但是如果一个序列很大,例如我们通过推导式来读取一个文件,则我们需要生成器表达式(个人理解为元祖推导式)来完成:
In[38]: ss = ((x + 1) for x in range(0, 1000))
In[39]: ss
Out[39]: <generator object <genexpr> at 0x108764cd0>
In[40]: for i in ss:
...     if i > 10:
...         break
...     print i,
...     
1 2 3 4 5 6 7 8 9 10
    假设是集合set,那么使用推导式则需要花括号:
In[42]: a = {x for x in 'abracadabra' if x not in 'abc'}
In[43]: a
Out[43]: {'d', 'r'}
In[44]: set(['d', 'r'])
Out[44]: {'d', 'r'}


6. 模块化

    在大型项目中,模块化是非常重要的.但是我们导入模块时候有两种方式,假设我们定义了一个模块文件:

__author__ = 'lgt'

def fib(n):
    a, b = 0, 1
    while b < n:
        print b,
        a, b = b, a + b

def fib2(n):
    result = []
    a, b = 0, 1
    while b < n:
        result.append(b)
        a, b = b, a + b
    return result
一般情况下我们会这样导入:
In[15]: import fibo
In[16]: fibo.fib(100)
1 1 2 3 5 8 13 21 34 55 89
In[17]: fibo.fib2(100)
Out[17]: [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
    但是有时候为了书写方便,我们往往会这样导入:
In[18]: from fibo import fib, fib2
In[19]: from fibo import *
In[20]: fib(100)
1 1 2 3 5 8 13 21 34 55 89
In[21]: fib2(100)
Out[21]: [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
    但是这会隐藏一个BUG.例如我们在另一个文件fibo1.py中定义了相同的fib函数:
__author__ = 'lgt'

def fib(n):
    print 'hello world'
那么那个模块最后导入,就使用那个模块:
In[22]: from fibo import *
In[23]: from fibo1 import *
In[24]: fib(100)
hello world
In[25]: from fibo1 import *
In[26]: from fibo import *
In[27]: fib(100)
1 1 2 3 5 8 13 21 34 55 89
    所以,具体取舍还是得靠程序员自己.

__name__ == '__main__'的妙用

    一般情况下,我们是需要对一个模块进行单元测试的编写的.这时我们往往可以在模块中添加类似如下指令:

if __name__ == '__main__':
    import sys
    fib(int(sys.argv[1]))
因为只有运行当前模块情况下,__name__才会等于'__main__',而如果其它模块调用它,则__name__等于'fibo'.


7. 序列化json

    序列化用代码就可以说明:

# -*- coding:utf-8 -*-
import json
f = open('test.txt', 'w')
json.dump([1, 'simple', 'list'], f)
f.close()

with open('test.txt', 'r') as f:
    for line in f:
        print line
        print type(line)

with open('test.txt', 'r') as f:
    x  = json.load(f)
    print x
    print type(x)
输出:
[1, "simple", "list"]
<type 'str'>
[1, u'simple', u'list']
<type 'list'>


8. 异常处理

    异常通常使用try ... catch 来捕获.而else表示没有产生异常时必须执行的语句,finally表示无论是否发生异常,都会被执行的语句:

# -*- coding:utf-8 -*-
import sys

try:
    a = 1 / 1
except (RuntimeError, TypeError, NameError) as e:
    print 'handler error', e
else:
    print 'no error'
finally:
    print 'finish'

#输出:
#no error
#finish
而产生异常的代码:
# -*- coding:utf-8 -*-
import sys

try:
    a = 1 / 0
except (RuntimeError, TypeError, NameError, ZeroDivisionError) as e:
    print 'handler error', e
else:
    print 'no error'
finally:
    print 'finish'

#输出:
#finish


9. Classes

1. Python的作用域和命名空间

    命名空间就是一堆对象的名字集合,而对象通常具有不同的生命周期.而作用域就是命名空间可以直接访问的文本域,且作用域通常是动态生成的(Python是解释性语言).

例如,我们定义一个函数func,则产生一个作用域:

# -*- coding:utf-8 -*-

def func():
    x = 1
    del x
    这是,执行x = 1实际上就是将变量x绑定到函数func所产生的作用域中,而del x就是接触绑定.

2. 类对象

    类对象支持两种操作: 属性引用和实例化.假设我们定义一个类:

class MyClass:
    """A simple example class"""
    i = 12345
    def __init__(self, i):
        self.i = i
    def f(self):
        return 'hello world'

属性引用:

print MyClass.i    #12345
MyClass.i = 10000
print MyClass.i    #10000
    而我们一般都使用实例化:
x = MyClass(12345)
print x.f()     #hello world
print x.i       #12345
3. 实例化变量

    类变量针对类而言,而实例化变量针对具体对象而言.假设我们编写如下代码:

# -*- coding:utf-8 -*-

class Dog:
    kind = 'canine'

    def __init__(self, name):
        self.name = name

d = Dog('Fido')
e = Dog('Buddy')
print d.kind    #canine
print e.kind    #canine
print d.name    #Fido
print e.name    #Buddy
    这里类变量和实例变量互不影响.但假设我们这样编写代码:
# -*- coding:utf-8 -*-

class Dog:
    tricks = []

    def __init__(self, name):
        self.name = name
    def add_trick(self, trick):
        self.tricks.append(trick)

d = Dog('Fido')
e = Dog('Buddy')
d.add_trick('roll over')
e.add_trick('play dead')
print d.tricks  #['roll over', 'play dead']
    这不是新需求,是BUG......

所以我们一般都是这样设计:

# -*- coding:utf-8 -*-

class Dog:
    def __init__(self, name):
        self.name = name
        self.tricks = []
    def add_trick(self, trick):
        self.tricks.append(trick)

d = Dog('Fido')
e = Dog('Buddy')
d.add_trick('roll over')
e.add_trick('play dead')
print d.tricks  #['roll over']

4. 继承

    Python中的继承机制如C++的虚拟继承,即所有的函数都可以被重写,可直接被调用,或者根本不调用:


# -*- coding:utf-8 -*-

class BaseClass(object):
    def __init__(self, name):
        self.baseName = name
    def show(self):
        print self.baseName
    def getName(self):
        return self.baseName
    def baseFunc(self):
        print "I'm baseClass"

class SubClass(BaseClass):
    def __init__(self, name, num):
        super(SubClass, self).__init__(name)
        self.subNum = num
    def show(self):
        super(SubClass, self).show()
        print self.subNum
    def getName(self):
        return self.baseName + str(self.subNum)

C = SubClass('lcj', 26)
#继承父函数
C.show()
#调用自身函数
print C.getName()
#调用父函数
C.baseFunc()
输出:



lcj
26
lcj26
I'm baseClass
    而Python中私有变量往往以__(双下划线开头),这在设计类的时候很有用:



# -*- coding:utf-8 -*-

class Mapping:
    def __init__(self, iterable):
        self.items_list = []
        #私有变量
        self.__update(iterable)
    def update(self, iterable):
        for item in iterable:
            self.items_list.append(item)

    __update = update

class MappingSubclass(Mapping):
    def update(self, keys, values):
        for item in zip(keys, values):
            self.items_list.append(item)

S = MappingSubclass([11, 12])
S.update(['a', 'b'], [1, 2])
#[11, 12, ('a', 1), ('b', 2)]
print S.items_list





© 著作权归作者所有

共有 人打赏支持
fzyz_sb
粉丝 404
博文 209
码字总数 447144
作品 0
武汉
程序员
Python学习日记六(Python连接MySql)

一.准备工作(下载MySQL-python和python安装包 ) Python需要连接mysql,需要下载Python MySQLdb模块,这里提供几个链接地址: MySQL-python官网下载地址 :https://pypi.python.org/pypi/My...

HaleyLiu ⋅ 04/12 ⋅ 0

Python 工具——Anaconda+Pycharm 的安装过程

适用对象:编程完全小白,准备安装 Python 进行学习 本文特点: 十分具体详细,细致到了每一步安装过程的截图,看了此篇,你完全不用看其他教程,给出了软件的百度云以及自己找到的可用的 Py...

xjtuhit ⋅ 05/07 ⋅ 0

年薪20万Python工程师进阶(1):Python 资源 + 经典练手项目

Python 越来越火爆,最近自己也在学习。整理下一些 Python 资料,和练手的项目。希望对你学习 Python 有所帮助。 1、入门阶段 1 Python 官网 Python 官网 The Python Tutorialdocs.python.o...

程序员八阿哥 ⋅ 05/11 ⋅ 0

良心推荐:一份20周学习计算机科学的经验贴(附资源)

雷锋网按:这里是,油管Artificial Intelligence Education专栏,原作者Siraj Raval授权雷锋字幕组编译。 原标题 Computer Science Curriculum 翻译 | 王飞 整理 | 凡江 这是一份五个月(20个...

雷锋字幕组 ⋅ 05/08 ⋅ 0

筒子们,免费学习《Python自动化测试开发实践》课啦,请接住~

经常会有人问: 蛋哥,最近有没有什么免费的技术课啊? 蛋哥,最近有什么关于Python的课程么? 蛋哥,最近有没有测试的直播课额? 蛋哥,…… 应广大群众的强烈呼唤,为了让大家尽可能多的学...

蜗牛学院 ⋅ 04/13 ⋅ 0

Eric:Python的IDE之eric的简介、安装、使用方法之详细攻略——Jason Niu

Eric的简介 Eric是一个完整的Python编辑器和IDE,用Python编写。它是基于跨平台QT-UI工具包,集成了高度灵活的闪烁编辑器控件。它被设计成可用作为“每日”的快速和肮脏的编辑器,以及作为一...

qq_41185868 ⋅ 05/24 ⋅ 0

centos 7 安装python3.6.1

centos7 默认安装了python2.7.5,当需要使用python3的时候,可以手动下载python源码后编译安装. python 官网:www.python.org 1.安装python可能用到的依赖 yum install openssl-devel bzip2-de...

limingyu0312 ⋅ 2017/07/11 ⋅ 0

VisualStudioCode插件下载

vscode的插件想离线安装,则先需要先行下载 插件官网 下载链接的模板 举例说明(Python插件) Python插件页面 其中 ${publisher}的值为ms-python ${extension name}的值为python ${version}...

t_huanghai ⋅ 06/21 ⋅ 0

Python-Jenkins API使用 —— 在后端代码中操控Jenkins

最近在工作中需要用到在后台代码中触发Jenkins任务的构建,于是想到Jenkins是否有一些已经封装好的API类库提供,用于处理跟Jenkins相关的操作。下面就简单介绍下我的发现。 Linux Curl   首...

yzy121403725 ⋅ 06/21 ⋅ 0

Mac OS搭建Python开发环境的几个误区

mac在配置Python开发环境中容易被迷惑的几个误区 个人觉得python发展前景挺好的,就决定自学一段时间python开发,但是在配置环境中就遇到了各种坑,下面就个人的简单说一下。 首先官网下载p...

coder_di ⋅ 05/22 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

个人博客的运营模式能否学习TMALL天猫质量为上?

心情随笔|个人博客的运营模式能否学习TMALL天猫质量为上? 中国的互联网已经发展了很多年了,记得在十年前,个人博客十分流行,大量的人都在写博客,而且质量还不错,很多高质量的文章都是在...

原创小博客 ⋅ 今天 ⋅ 0

JavaScript零基础入门——(十一)JavaScript的DOM操作

JavaScript零基础入门——(十一)JavaScript的DOM操作 大家好,欢迎回到我们的JavaScript零基础入门。最近有些同学问我说,我讲的的比书上的精简不少。其实呢,我主要讲的是我在开发中经常会...

JandenMa ⋅ 今天 ⋅ 0

volatile和synchronized的区别

volatile和synchronized的区别 在讲这个之前需要先了解下JMM(Java memory Model :java内存模型):并发过程中如何处理可见性、原子性、有序性的问题--建立JMM模型 详情请看:https://baike.b...

MarinJ_Shao ⋅ 今天 ⋅ 0

深入分析Kubernetes Critical Pod(一)

Author: xidianwangtao@gmail.com 摘要:大家在部署Kubernetes集群AddOn组件的时候,经常会看到Annotation scheduler.alpha.kubernetes.io/critical-pod"="",以表示这是一个关键服务,那你知...

WaltonWang ⋅ 今天 ⋅ 0

原子性 - synchronized关键词

原子性概念 原子性提供了程序的互斥操作,同一时刻只能有一个线程能对某块代码进行操作。 原子性的实现方式 在jdk中,原子性的实现方式主要分为: synchronized:关键词,它依赖于JVM,保证了同...

dotleo ⋅ 今天 ⋅ 0

【2018.06.22学习笔记】【linux高级知识 14.4-15.3】

14.4 exportfs命令 14.5 NFS客户端问题 15.1 FTP介绍 15.2/15.3 使用vsftpd搭建ftp

lgsxp ⋅ 今天 ⋅ 0

JeeSite 4.0 功能权限管理基础(Shiro)

Shiro是Apache的一个开源框架,是一个权限管理的框架,实现用户认证、用户授权等。 只要有用户参与一般都要有权限管理,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户...

ThinkGem ⋅ 昨天 ⋅ 0

python f-string 字符串格式化

主要内容 从Python 3.6开始,f-string是格式化字符串的一种很好的新方法。与其他格式化方式相比,它们不仅更易读,更简洁,不易出错,而且速度更快! 在本文的最后,您将了解如何以及为什么今...

阿豪boy ⋅ 昨天 ⋅ 0

Python实现自动登录站点

如果我们想要实现自动登录,那么我们就需要能够驱动浏览器(比如谷歌浏览器)来实现操作,ChromeDriver 刚好能够帮助我们这一点(非谷歌浏览器的驱动有所不同)。 一、确认软件版本 首先我们...

blackfoxya ⋅ 昨天 ⋅ 0

线性回归原理和实现基本认识

一:介绍 定义:线性回归在假设特证满足线性关系,根据给定的训练数据训练一个模型,并用此模型进行预测。为了了解这个定义,我们先举个简单的例子;我们假设一个线性方程 Y=2x+1, x变量为商...

wangxuwei ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部