Python 中 Iterator和python iterable 对象的区别

iterable|LOFTER(乐乎) - 记录生活,发现同好
LOFTER for ipad —— 记录生活,发现同好
&nbsp&nbsp被喜欢
&nbsp&nbsp被喜欢
{list posts as post}
{if post.type==1 || post.type == 5}
{if !!post.title}${post.title|escape}{/if}
{if !!post.digest}${post.digest}{/if}
{if post.type==2}
{if post.type == 3}
{if !!post.image}
{if post.type == 4}
{if !!post.image}
{if !!photo.labels && photo.labels.length>0}
{var wrapwidth = photo.ow < 500?photo.ow:500}
{list photo.labels as labs}
{var lbtxtwidth = Math.floor(wrapwidth*(labs.ort==1?labs.x:(100-labs.x))/100)-62}
{if lbtxtwidth>12}
{if !!labs.icon}
{list photos as photo}
{if photo_index==0}{break}{/if}
品牌${make||'-'}
型号${model||'-'}
焦距${focalLength||'-'}
光圈${apertureValue||'-'}
快门速度${exposureTime||'-'}
ISO${isoSpeedRatings||'-'}
曝光补偿${exposureBiasValue||'-'}
镜头${lens||'-'}
{if data.msgRank == 1}{/if}
{if data.askSetting == 1}{/if}
{if defined('posts')&&posts.length>0}
{list posts as post}
{if post_index < 3}
{if post.type == 1 || post.type == 5}
{if !!post.title}${post.title|escape}{/if}
{if !!post.digest}${post.digest}{/if}
{if post.type == 2}
{if post.type == 3}
{if post.type == 4}
{if drlist.length>0}
更多相似达人:
{list drlist as dr}{if drlist.length === 3 && dr_index === 0}、{/if}{if drlist.length === 3 && dr_index === 1}、{/if}{if drlist.length === 2 && dr_index === 0}、{/if}{/list}
暂无相似达人,
{if defined('posts')&&posts.length>0}
{list posts as post}
{if post.type == 2}
{if post.type == 3}
{if post.type == 4}
this.p={ currentPage:1,pageNewMode:true,isgooglead3:false,ishotrecompost:false,visitorId:0, first:'',tag:'iterable',recommType:'total',recommenderRole:0,offset:2,type:0,isUserEditor:0,};新手园地& & & 硬件问题Linux系统管理Linux网络问题Linux环境编程Linux桌面系统国产LinuxBSD& & & BSD文档中心AIX& & & 新手入门& & & AIX文档中心& & & 资源下载& & & Power高级应用& & & IBM存储AS400Solaris& & & Solaris文档中心HP-UX& & & HP文档中心SCO UNIX& & & SCO文档中心互操作专区IRIXTru64 UNIXMac OS X门户网站运维集群和高可用服务器应用监控和防护虚拟化技术架构设计行业应用和管理服务器及硬件技术& & & 服务器资源下载云计算& & & 云计算文档中心& & & 云计算业界& & & 云计算资源下载存储备份& & & 存储文档中心& & & 存储业界& & & 存储资源下载& & & Symantec技术交流区安全技术网络技术& & & 网络技术文档中心C/C++& & & GUI编程& & & Functional编程内核源码& & & 内核问题移动开发& & & 移动开发技术资料ShellPerlJava& & & Java文档中心PHP& & & php文档中心Python& & & Python文档中心RubyCPU与编译器嵌入式开发驱动开发Web开发VoIP开发技术MySQL& & & MySQL文档中心SybaseOraclePostgreSQLDB2Informix数据仓库与数据挖掘NoSQL技术IT业界新闻与评论IT职业生涯& & & 猎头招聘IT图书与评论& & & CU技术图书大系& & & Linux书友会二手交易下载共享Linux文档专区IT培训与认证& & & 培训交流& & & 认证培训清茶斋投资理财运动地带快乐数码摄影& & & 摄影器材& & & 摄影比赛专区IT爱车族旅游天下站务交流版主会议室博客SNS站务交流区CU活动专区& & & Power活动专区& & & 拍卖交流区频道交流区
白手起家, 积分 10, 距离下一级还需 190 积分
论坛徽章:0
min(&&& & & & iterable[, args...][key])
& & With a single argument iterable, return the smallest item of a non-empty iterable (such as a string, tuple or list). With more than one argument, return the smallest of the arguments.
& & The optional key argument specifies a one-argument ordering function like that used for list.sort(). The key argument, if supplied, must be in keyword form (for example, &min(a,b,c,key=func)&). Changed in version 2.5: Added support for the optional key argument.
&&nbsp|&&nbsp&&nbsp|&&nbsp&&nbsp|&&nbsp&&nbsp|&&nbsp
家境小康, 积分 1613, 距离下一级还需 387 积分
论坛徽章:0
就是可以通过for 这种形式一个个取出值来的变量,如list, tuple, dict,自已也可以定义特殊的方法来使自定义类支持这种操作
白手起家, 积分 10, 距离下一级还需 190 积分
论坛徽章:0
est 该用户已被删除
提示: 作者被禁止或删除 内容自动屏蔽
家境小康, 积分 1613, 距离下一级还需 387 积分
论坛徽章:0
看我以前写的blogLang-Python - 简书
下载简书移动应用
写了28258字,被2人关注,获得了3个喜欢
Lang-Python
个人笔记,方便自己查阅使用
Py.LangSpec.Contents
Collections
Data Structures
Dictionary
Comprehension
List Comprehensions
Data Structures (Implementations)
Decorators
Parameters& Arguments
Generators, yield, Iterables
Grammar/Syntax
Lambda, filter, reduce and map
Object and Class
class variables
Object Types
检查空对象?
Variables, Objects, Types, References
python中的变量 和 引用
强类型,弱类型?
Global vars
With..as..
Commandline
Concurrency
Errors you meet
Garbage Collection
Regular Expression
System&Software
Questions/Problems
Lang Py 2.7
The compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1) built-in can be used to speed up repeated invocations of the same code with exec or eval by compiling the source into a code object beforehand.
Compile the source into a code or AST object. Code objects can be executed by an exec statement or evaluated by a call to eval().
eval, exec
The exec function (which was a statement in Python 2) is used for executing a dynamically created statement or program
only exec accepts source code that contains statements like def, for, while, import, or class
Both exec and eval accept 2 additional positional arguments - globals and locals - which are the global and local variable scopes that the code sees.
Python’s closures are late binding. This means that the values of variables used in closures are looked up at the time the inner function is called. (RUNTIME)
def multipliers():
return [lambda x : i * x for i in range(4)]
print [m(2) for m in multipliers()]
The output of the above code will be [6, 6, 6, 6] (not [0, 2, 4, 6]).
The reason for this is that Python’s closures are late binding. This means that the values of variables used in closures are looked up at the time the inner function is called. So as a result, when any of the functions returned by multipliers() are called, the value of i is looked up in the surrounding scope at that time. By then, regardless of which of the returned functions is called, the for loop has completed and i is left with its final value of 3. Therefore, every returned function multiplies the value it is passed by 3, so since a value of 2 is passed in the above code, they all return a value of 6 (i.e., 3 x 2).
对于这个例子,重要的一个点是,for i in range(4)是不属于这个lambda函数的,所以multipliers返回的是一个含有4个function的列表。late binding告诉我们,运行该lambda函数的时候,我们才计算函数的内容(也不一定要是lambda,一般的函数也可以,因为我们这里是讨论闭包),而彼时i已经变成3。这个问题的难度在于,把列表推导式使用的变量与lambda函数调用的变量用到了一起,再加上了闭包。
Collections
OrderedDict
有序的字典对象
OrderedDict.popitem(last=True)
The popitem() method for ordered dictionaries returns and removes a (key, value) pair. The pairs are returned in LIFO order if last is true or FIFO order if false.
Data Structures (Types)
or: Sequence
del 用del来删除dict/list中的一个/多个元素,比使用remove要快
Dictionary
Dictionary Mapping for Functions
Comprehension
In Python 2.6 and earlier, the dict constructor can receive an iterable of key/value pairs:
d = dict((key, value) for (key, value) in iterable)
From Python 2.7 and 3 onwards, you can just use the dict comprehension syntax directly:
d = {key: value for (key, value) in iterable}
注意:字典元素的顺序通常没有定义。换句话说,迭代的时候,字典中的键和值都能保证被处理,但是处理顺序不确定。如果顺序很重要的话,可以将键值保存在单独的列表中,例如迭代前进行排序。
items() --& a list of tuples : for k,v in d.iteritems() 也可以加上括号 for (k,v) in
dict.items()
iteritems() - iterator-generator -& for k,v in d.iteritems() 也可以加上括号
Initialization 初始化
plist = ['a',1,obj1]
plist = ["wulala"] 得到 ['wulala']
plist = list() 空列表 或者 plist=[]
NOTE: plist = list["wula"]
会得到 ['w','u','l','a']
print li[::-1]
#输出[7,6,5,4,3,2,1],省略起始索引、终止索引,步长值为-1,表示反向获取
倒序输出列表
range()返回列表
range(0,3)[::-1]
#输出[2,1,0]
the statement list = [ [ ] ] * 5 does NOT create a list containing 5 distinct rather, it creates a a list of 5 references to the same list (i.e. [] here)
list[0].append(10) appends 10 to the first list. But since all 5 lists refer to the same list, the output is: [[10], [10], [10], [10], [10]].
Similarly, list[1].append(20) appends 20 to the second list. But again, since all 5 lists refer to the same list, the output is now: [[10, 20], [10, 20], [10, 20], [10, 20], [10, 20]].
In contrast, list.append(30) is appending an entirely new element to the “outer” list, which therefore yields the output: [[10, 20], [10, 20], [10, 20], [10, 20], [10, 20], 30].
List Comprehensions
Generator Comprehension, Set Comprehension, etc
list comprehension中,只能使用for和if这2种语句。
a = 5 if b & 3 else 2 (python 中没有?:)
Q:Python的List Comprehension中,可以使用无限多个for、if语句,该怎么去理解这些for、if语句呢?它们之间的关系是什么呢?
A: Python的语法解析、字节码生成,大约分为3个阶段:
1、将.py源代码,解析成语法树
2、将语法树,解析成AST树
3、根据AST树,生成字节码
Python在从语法树生成AST的过程中,会将List Comprehension中的for分离开来,并将每个if语句,全部归属于离他最近的左边的for语句
如果变量x没有被使用过,那么变量x会成为一个局部变量,当列表推导式结束后,还可以访问变量x;否则,变量x原来的作用域是什么,现在还是什么。
后续的for语句都嵌套在之前的for语句中
Set Comprehension: use curly brackets instead of square brackets to create a set.
no_primes = {j for i in range(2,sqrt_n) for j in range(i*2, n, i)}
S = [x**2 for x in range(10)]
V = [2**i for i in range(13)]
M = [x for x in S if x % 2 == 0] ## [0, 4, 16, 36, 64]
m = [x for x in [x**2 for x in range(10)] if x%2==0] ## [0, 4, 16, 36, 64]
&&& noprimes = [j for i in range(2, 8) for j in range(i*2, 50, i)] # 倘若写成 noprimes = [j for j in range(i*2, 50, i) for i in range(2, 8) ] 就不是本来的意思了,因为后续的for语句都嵌套在之前的for语句中
primes = [x for x in range(2, 50) if x not in noprimes]
&&& print primes
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
[(x,y,z) for x in range(1,30) for y in range(x,30) for z in range(y,30) if x**2 + y**2 == z**2]
you can nest list comprehensions inside of each other, so you could write the above example with a single statement (without the need for the temporary variable "noprimes").
Data Structures (Implementations)
Decorators
A decorator is a function that expects ANOTHER function as parameter
a wrapper can be seen as a wrapper of another function
notice the arg, and what the decorator returns (a function)
try...except[SomeError]; try... raise触发异常
e.g. raise ShortInputException(len(s), 3)
处理:except ShortInputException, xs:
函数里的语句在函数定义时并不执行,只有在该function being called的时候才执行
zip([seql, ...])接受一系列可迭代对象作为参数,将对象中对应的元素打包成一个个tuple(元组),然后返回由这些tuples组成的list(列表)。若传入参数的长度不等,则返回list的长度和参数中长度最短的对象相同。
zip()配合*号操作符,可以将已经zip过的列表对象解压
Parameters & Arguments
在python中,类型属于对象,变量是没有类型的.
所有的变量都可以理解是内存中一个对象的“引用”,或者,也可以看似c中void*的感觉。所以,希望大家在看到一个python变量的时候,把变量和真正的内存对象分开。
“可更改”(mutable)与“不可更改”(immutable)对象:在python中,strings, tuples, 和numbers是不可更改的对象,而list,dict等则是可以修改的对象。
传递参数的时候,python不允许程序员选择采用传值还是传引用。Python参数传递采用的肯定是“传对象引用”的方式。实际上,这种方式相当于传值和传引用的一种综合。
如果函数收到的是一个可变对象(比如字典或者列表)的引用,就能修改对象的原始值--相当于通过“传引用”来传递对象。
如果函数收到的是一个不可变对象(比如数字、字符或者元组)的引用,就不能直接修改原始对象--相当于通过“传值'来传递对象。
* 包裹传递: 所有的参数被收集,根据位置合并成一个元组(tuple)
** 包裹关键字传递:所有的参数被收集,根据位置和关键字合并成一个字典(dict)
解包裹传递: 就是在传递tuple时,让tuple的每一个元素对应一个位置参数; dict的解包裹类似
如果默认参数是一个mutable,而多次调用此function时,使用了该默认参数,会怎样呢?
See question 1
expressions in default arguments are calculated when the function is defined, not when it’s called.
Generators, yield, Iterables
Generators functions allow you to declare a function that behaves like an iterator, i.e. it can be used in a for loop.
Generators are iterators, but you can only iterate over them once(第二次不会报错,但什么也不会发生). It's because they do not store all the values in memory, they generate the values on the fly
Yield is a keyword that is used like return, except the function will return a generator.
IMPORTANT: when you call the function (with yield), the code you have written in the function body does not run. The function only returns the generator object
extend() 是一个迭代器方法,作用于迭代器,并把参数追加到迭代器的后面
yield 简单说来就是一个生成器,生成器是这样一个函数,它记住上一次返回时在函数体中的位置。对生成器函数的第二次(或第 n 次)调用跳转至该函数中间,而上次调用的所有局部变量都保持不变。
GREAT TUT:
考虑可复用性,并且节省内存占用
带有 yield 的函数在 Python 中被称之为 generator(生成器)
Generator Comprehension
Generator comprehensions were introduced with Python 2.6. They are simply a generator expression with a parenthesis - round brackets - around it. Otherwise, the syntax and the way of working is like list comprehension, but a generator comprehension returns a generator instead of a list
 Grammar/Syntax
Late Binding
input() uses raw_input to read a string of data, and then attempts to evaluate it as if it were a Python program, and then returns the value that results.
File objects are implemented using C’s stdio package and can be created with the built-in open() function.
It is an iterator
it can only traverse the file once.
You may reset the file cursor with .seek(0)
Actually, C's stdio is also streaming
想要print始终显示在同一行,本身是在最后加上逗号即可,即:print "xxx",
然后又想要实现,新打印的一行,冲掉之前旧的一行,达到显示出下载文件大小一点点增加,但是却始终保持同行,那么就再打印的内容最后添加上\r即可:print "xxx\r",
Stream - io module
The io module provides the Python interfaces to stream handling. Under Python 2.x, this is proposed as an alternative to the built-in file object, but in Python 3.x it is the default interface to access files and streams.
An iterable is an object that has an __iter__ method which returns an iterator, or which defines a __getitem__ method that can take sequential indexes starting from zero (and raises an IndexError when the indexes are no longer valid). So an iterable is an object that you can get an iterator from.
An iterator is an object with a next (Python 2) or __next__ (Python 3) method.
Whenever you use a for loop, or map, or a list comprehension, etc. in Python, the next method is called automatically to get each item from the iterator, thus going through the process of iteration.
Lambda, filter, reduce and map
Lambda functions are mainly used in combination with the functions filter(), map() and reduce(). The lambda feature was added to Python due to the demand from Lisp programmers.
只能由一条表达式组成
一般可以在sorted, max, 这类函数里的key用lambda.比如有一个比较复杂的数组结构,s = [('a', 3), ('b', 2), ('c', 1)]
对这个数组用第二个元素排序。可以写成 sorted(s, key=lambda x:x[1])map
r = map(func, seq)
r=map(lambda x: x+"abc","gre") # r为['gabc', 'rabc', 'eabc']
map() can be applied to more than one list (or sequence). The lists have to have the same length and the function or lambda should be able to take more than one args.
filter(function, list) offers an elegant way to filter out all the elements of a list, for which the function function returns True.
reduce(func, seq) continually applies the function func() to the sequence seq. It returns a single value.
it goes: [ func(func(s1, s2),s3), ... , sn ]
reduce(lambda x,y: x+y, [47,11,42,13]) ==&113
f = lambda a,b: a if (a & b) else b
reduce(f, [47,11,42,102,13])
if条件语句后面需要跟随bool类型的数据,即True或者False。然而,如果不是bool类型的数据,可以(自动)将其转换成bool类型的数据,转换的过程是隐式的。在Python中,None、空列表[]、空字典{}、空元组()、0等一系列代表空和无的对象会被转换成False。除此之外的其它对象都会被转化成True。在命令if not 1中,1便会转换为bool类型的True。not是逻辑运算符非,not 1则恒为False。因此if语句if not 1之下的语句,永远不会执行。
there is no else if in Python, only elif
Object and Class
Classes are objects too
This object (the class) is itself capable of creating objects (the instances), and this is why it's a class.
you can assign it to a variable
you can copy it
you can add attributes to it
you can pass it as a function parameter
Creating classes dynamically: like creating any object
e.g: in a function
type方法能动态的创建类: 接受一个类的描述作为参数,然后返回一个类
为你的类增加方法? define a function with the proper signature and assign it as an attribute=&放入type的dictionary 参数中
Class variables
in Python, class variables are internally handled as dictionaries. If a variable name is not found in the dictionary of the current class, the class hierarchy (i.e., its parent classes) are searched until the referenced variable name is found (if the referenced variable name is not found in the class itself or anywhere in its hierarchy, an AttributeError occurs).
if any of its child classes overrides that value, then the value is changed in that child only.
if the value is then changed in the Parent, that change is reflected also by any children that have not yet overridden the value
Class and its object
import copy
copy.copy(x)
Return a shallow copy of x.
copy.deepcopy(x)
Return a deep copy of x.
利用切片操作和工厂方法list方法拷贝就叫浅拷贝,只是拷贝了最外围的对象本身,内部的元素都只是拷贝了一个引用而已。 id 一样
利用copy中的deepcopy方法进行拷贝就叫做深拷贝,外围和内部元素都进行了拷贝对象本身,而不是引用。 id 不同
Python中的对象之间赋值时是按引用传递的,如果需要拷贝对象,需要使用标准库中的copy模块。
copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象。
copy.deepcopy 深拷贝 拷贝对象及其子对象
Instantiation 实例化
Python 的构造函数有两个,一个是我们最常用的 init ,另一个是很少用到的 new 。而从它们的函数定义 def new(cls, [...]) 和 def init(self, [...]) 可以知道, init 被调用时实例已经被创建(就是 self 参数所引用的);而 new 被调用的时候,实例不一定已被创建(暂时只能这么说),而 new 的第一个参数为当前类的引用。
Python以引用方式管理对象,你可以交换引用,但通常不能交换内存中的对象值。当然你也不需要这样做。举例:
# Definition for a binary tree node.
# class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
t = root.left
root.left = root.right
root.right = t
root.left, root.right = root.right, root.left
Object Types
Assignment:
所谓“传值”也就是赋值的意思.
Python不允许程序员选择采用传值还是传引用。Python参数传递采用的肯定是“传对象引用”的方式。实际上,这种方式相当于传值和传引用的一种综合。如果函数收到的是一个可变对象(比如字典或者列表)的引用,就能修改对象的原始值——相当于通过“传引用”来传递对象。如果函数收到的是一个不可变对象(比如数字、字符或者元组)的引用,就不能直接修改原始对象——相当于通过“传值”来传递对象。
当人们复制列表或字典时,就复制了对象列表的引用,如果改变引用的值,则修改了原始的参数
检查类型:
isinstance(obj, class)
+ `isinstance(obj, basestring)` for an object-to-test obj.
+ [basestring](https://docs.python.org/2/library/functions.html#basestring)
空对象? 检查空对象?
要返回空?
return: 返回None,不是False也不是True
return []: [],bool值为False
You use == when comparing values and is when comparing identities.
"Comparisons to singletons like None should always be done with 'is' or 'is not', never the equality operators."
"is" is a quick id comparison, whereas "==" requires a dict lookup on both the "1" and "None" objects for the comparison operators
None是一个特殊的常量。
None is actually a null object!
None和False不同。但None的布尔值是False+ False的有None, 0, []
None不是0。None不是空字符串。None和任何其他的数据类型比较永远返回False。None有自己的数据类型NoneType。你可以将None复制给任何变量,但是你不能创建其他NoneType对象。number
整数取整:小数点后的都不要(所以是向0取整)(经过测试)
Python 2 automatically performs integer arithmetic if both operands are integers. As a result, 5/2 yields 2, while 5./2 yields 2.5.
the “double-slash” (//) operator will always perform integer division, regardless of the operand types. That’s why 5.0//2.0 yields 2.0 even in Python 2.
Python 2中:
print x//y
结果是2.25
5//2 结果 2
Python3中除法“/”变成了浮点除法,不默认整数除法,而//则保留仍然进行整数除法
Scope 作用域
: global name
is not defined
在Python中,只有模块,类以及函数才会引入新的作用域,其它的代码块是不会引入新的作用域的。
在Python中,使用一个变量之前不必预先声明它,但是在真正使用它之前,它必须已经绑定到某个对象;而名字绑定将在当前作用域中引入新的变量,同时屏蔽外层作用域中的同名变量,不论这个名字绑定发生在当前作用域中的哪个位置。
用索引引用string时,string可被视为big-endian
str1= "1234", 则str1[0]=="1"
Case 大小写
Python string comparison is naturally case sensitive!
字符串操作
截取字符串
str[0:3] #截取第一位到第三位的字符,即前闭后开
检查和匹配
s.isdigit() 所有字符都是数字
str.isalpha 检查string是否全是alphabet,大写也符合!
检查字符串是否为空
if not myString:
isinstance(obj, basestring) for an object-to-test obj.
join 字符串连接
当一条命令用续行符 (“\”) 分割成多行时, 后续的行可以以任何方式缩近, 此时 Python 通常的严格的缩近规则无需遵守。
在小括号, 方括号或大括号中的表达式 (如 定义一个 dictionary) 可以用或者不用续行符 (“\”) 分割成多行。
Variables, Objects, Types, References
 python中的变量 和 引用
变量存储在内存中的值。这就意味着在创建变量时会在内存中开辟一个空间。基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中。因此,变量可以指定不同的数据类型,这些变量可以存储整数,小数或字符。
变量在内存中存储时,包含的信息:id,名称,数据,数据类型(由解释器决定)
Python的所有变量其实都是指向内存中的对象的一个指针/引用,所有的变量都是。此外,对象还分两类:一类是可修改的,一类是不可修改的。
调用函数时,把参数里传入的东西对相应对象的引用依次赋给对应的内部变量。而此时,则要考虑到,外部namespace和函数内部namespace的隔离。
 全局变量和本地变量
如果一个函数里面使用了一个变量,那么 Python 会先看看有没有对应的本地变量,如果没有找到,但找到一个全局变量,那么 Python 会把那个全局变量的引用赋给一个新的本地变量。所以,现在在函数里的那个变量和全局变量其实不是同一个变量,他们只不过暂时有了相同的引用。这样其实可以看作 Python 为你做了隐式的参数传递。 ==&& 局部里修改一个全局变量,全局变量会改变
强类型,弱类型?
Python 是强类型语言?
是:"1"+2 you will get traceback error
强、弱类型
强类型strongly typed: 如果一种语言的所有程序都是well behaved——即不可能出现forbidden behaviors,则该语言为strongly typed。弱类型weakly typed: 否则为weakly typed。比如C语言的缓冲区溢出,属于trapped errors,即属于forbidden behaviors..故C是弱类型
弱类型语言,类型检查更不严格,如偏向于容忍隐式类型转换。譬如说C语言的int可以变成double。 这样的结果是:容易产生forbidden behaviours,所以是弱类型的
动态、静态类型
静态类型 statically: 如果在编译时拒绝ill behaved程序,则是动态类型dynamiclly: 如果在运行时拒绝ill behaviors, 则是dynamiclly typed。静态类型可以分为两种:如果类型是语言语法的一部分,在是explicitly typed显式类型;如果类型通过编译时推导,是implicity typed隐式类型, 比如ML和Haskell
无类型: 汇编弱类型、静态类型 : C/C++弱类型、动态类型检查: Perl/PHP强类型、静态类型检查 :Java/C#强类型、动态类型检查 :Python, Scheme静态显式类型 :Java/C静态隐式类型 :Ocaml, Haskell
Global vars
应该尽量避免使用Python全局变量。不同的模块都可以自由的访问全局变量,可能会导致全局变量的不可预知性。
With..as..
Python对with的处理基本思想是with所求值的对象必须有一个enter()方法,一个exit()方法。
Commandline
The Python sys module provides access to any command-line arguments via the sys.argv (list)
Run programs from commandline
run python bin/app.py would go, but cd bin/, python app.py would go wrong.
In all Python projects you do not cd into a lower directory to run things. You stay at the top and run everything from there so that all of the system can access all the modules and files.
Concurrency
对于任何Python程序,不管有多少的处理器,任何时候都总是只有一个线程在执行。 "不要使用多线程,请使用多进程。"GIL对诸如当前线程状态和为垃圾回收而用的堆分配对象这样的东西的访问提供着保护。然而,这对Python语言来说没什么特殊的,它需要使用一个GIL。这是该实现的一种典型产物。现在也有其它的Python解释器(和编译器)并不使用GIL。虽然,对于CPython来说,自其出现以来已经有很多不使用GIL的解释器。
由于GIL,python的多线程,threading非常适合i/o密集,而不适合cpu密集。如果要利用多核,则要使用Multiprocessing。
multiprocessing pool & dummy
multiprocessing.dummy 是 multiprocessing 模块的完整克隆,唯一的不同在于 multiprocessing 作用于进程,而 dummy 模块作用于线程; 可以针对 IO 密集型任务和 CPU 密集型任务来选择不同的库. IO 密集型任务选择multiprocessing.dummy,CPU 密集型任务选择multiprocessing.
multiprocessing.dummy 模块与 multiprocessing 模块的区别: dummy 模块是多线程,而 multiprocessing 是多进程, api 都是通用的。 所有可以很方便将代码在多线程和多进程之间切换。
multiprocessing.dummy replicates the API of multiprocessing but is no more than a wrapper around the threading module.
multiprocessing.pool和dummy都可以使用map来简化多线程
Global Interpreter Lock ,意即全局解释器锁
在 Python 语言的主流实现 CPython 中,GIL 是一个货真价实的全局线程锁,在解释器解释执行任何 Python 代码时,都需要先获得这把锁才行,在遇到 I/O 操作时会释放这把锁。如果是纯计算的程序,没有 I/O 操作,解释器会每隔 100 次操作就释放这把锁,让别的线程有机会执行(这个次数可以通过 sys.setcheckinterval 来调整)。
所以虽然 CPython 的线程库直接封装操作系统的原生线程,但 CPython 进程做为一个整体,同一时间只会有一个获得了 GIL 的线程在跑,其它的线程都处于等待状态等着 GIL 的释放。
这也就解释了之前的实验结果:虽然有两个死循环的线程,而且有两个物理 CPU 内核,但因为 GIL 的限制,两个线程只是做着分时切换,总的 CPU 占用率还略低于 50%。
历史原因:多核 CPU 在 1990 年代还属于类科幻,Guido van Rossum 在创造 python 的时候,也想不到他的语言有一天会被用到很可能 1000+ 个核的 CPU 上面,一个全局锁搞定多线程安全在那个时代应该是最简单经济的设计了。简单而又能满足需求,那就是合适的设计
Python 在 2.6 里新引入了 multiprocessing 这个多进程标准库,让多进程的 python 程序编写简化到类似多线程的程度,大大减轻了 GIL 带来的不能利用多核的尴尬。
C拓展:如果不想用多进程这样重量级的解决方案,还有个更彻底的方案,放弃 Python,改用 C/C++。当然,你也不用做的这么绝,只需要把关键部分用 C/C++ 写成 Python 扩展,其它部分还是用 Python 来写,让 Python 的归 Python,C 的归 C。一般计算密集性的程序都会用 C 代码编写并通过扩展的方式集成到 Python 脚本里(如 NumPy 模块)。在扩展里就完全可以用 C 创建原生线程,而且不用锁 GIL,充分利用 CPU 的计算资源了。不过,写 Python 扩展总是让人觉得很复杂。
ctypes: Python 还有另一种与 C 模块进行互通的机制 : ctypes
利用 ctypes 绕过 GIL: ctypes 与 Python 扩展不同,它可以让 Python 直接调用任意的 C 动态库的导出函数。
Python中开线程,用C跑
Python 3.2 -& New GIL
在新的GIL实现中,用一个固定的超时时间来指示当前的线程放弃全局锁。在当前线程保持这个锁,且其他线程请求这个锁的时候,当前线程就会在5ms后被强制释放掉这个锁。
pyCharm (from JetBrains)
理解unicode, utf-8
unicode是字符集的映射(编码的映射),utf-8等等是编码方式(在计算机中怎么存储)。 gbk,ascii也是编码,不过不是对应unicode字符集。
unicode用数字0-0x10FFFF来映射字符
UTF-8、UTF-16、UTF-32都是将数字转换到程序数据的编码方案。一个unicode编码按16进制很明显会超过一个字节,所以如何按字节存储于计算机中,就是编码方案。
通用字符集(Universal Character Set, UCS)是由ISO制定的ISO 10646(或称ISO/IEC 10646)标准所定义的标准字符集。UCS-2用两个字节编码,UCS-4用4个字节编码。
\u7edf\u4e00\u7801("统一码")便是一个unicode编码序列
Python's encoding problems
Source code encoding
Python will default to ASCII as standard encoding if no otherencoding hints are given.
To define a source code encoding, a magic comment must be placed into the source files either as first or second line in the file, such as:
# coding=&encoding name&
#!/usr/bin/python
# -*- coding: &encoding name& -*-
More precisely, the first or second line must match the regular expression "coding[:=]\s*([-\w.]+)".
\s matches any whitespace character
\w matches any alphanumeric character and the underscore
\W matches any non-alphanumeric character
Unicode? String?
任何两种字符编码之间如果想完成转化,必须要通过unicode这个桥梁,先把它转化成unicode对象;+ unicode对象直接进行输出,往往会出现乱码,需要解码成str对象。
str.encode()实际上就等价于str.decode(sys.defaultencoding).encode();而python的默认编码则是ascii
unicode(string [, encoding[, errors]]) -& object这个函数的作用是将string按照encoding的格式编码成为unicode对象。
u"xxx"对应于unicode("xxx", 'utf-8') (如果文件/字符串编码是utf-8)
首先要注意区分,一个字符的不同stage,
在编辑器中输入时是一个stage(或者说在文件/磁盘中存在是一个stage),此时的编码由文件的encoding决定
而在python程序中存在为一个对象时,是第二个stage;
输出(比如在命令行)时,则是第三个stage。
u"笔记"在python程序中,将存在为一个unicode对象(type unicode),即 u'\u7b14\u8bb0'
print u"笔记"将输出 笔记
而对于string="笔记",则仍是一个string对象,直接输出会显示乱码。正确输出,需要先经过两步,
string.decode("utf-8") 假定python程序文件的保存方式是utf-8, 这时候,string仍是一个str type
然后用newstr = unicode(string, 'utf-8')输出,则可以得到正确输出 笔记 . 这时,newstr是一个 unicode type
u"xxx"的意思是,xxx是一个Unicode编码序列,所以xxx进入python程序时,就会被作为unicode来处理,因此print之,也是正确的输出。
查看系统的encoding
import sys
sys.stdout.encoding
cp936(microsoft) =& GBK
在python中,编码:unicode--&解码str--&unicode.既然是编码,那么就和密码领域一样,编码和解码自然涉及到编码/解码方案(对应加密或者解密算法),unicode相当于明文。在python中,编码函数是encode(),解码函数是decode()。需要注意的一点是,如果我们调用str.encode(),这里涉及到一个隐式的类型转化,会现将str转化成unicode,才能进行编码,这也是不太容易理解的地方。所以,str.encode()实际上就等价于str.decode(sys.defaultencoding).encode().而sys.defaultencoding一般是ascii,它是不能用来编码中文字符的。
python默认采用ascii编码,而中文编码不在ascii编码能够表示的范围之内,所以string无法将“我的”作为ascii编码保存为str类型。
字符编码/解码函数:
unicode:这个是python的内建函数,位于unicode类。unicode(string [, encoding[, errors]]) -& object这个函数的作用是将string按照encoding的格式编码成为unicode对象。省略参数将用python默认的ASCII来解码
举例:unicode(someChineseString, "utf-8") 则是将字符按照utf8格式转换成unicode
任何两种字符编码之间如果想完成转化,必须要通过unicode这个桥梁,先把它抓化成unicode对象;unicode对象直接进行输出,往往会出现乱码,需要解码成str对象。
在python中需要使用unicode需要注意:
程序中出现字符串时一定要加一个前缀u
不要用str()函数,用Unicode()代替
不要用过时的string模块。如果传给它非ASCII码,它会把一切搞砸。
不到必须时不要在你的程序里编解码Unicode字符,只在你要写入文件或者数据库或者网络时,才调用encode()函数和decode()函数。
使用什么字符编码,就要采用对应的字符集进行解码
内建的str()函数和chr()函数不能处理Unicode,它们只能处理常规ASCII编码的字符串,如果一个Unicode字符串作为参数传给了str()函数,它会首先被转换成ASCII码字符串然后交给str()函数。
import unicodedata
find a character's Unicode name?
get Unicode character's codepoint in decimal?
get the Unicode char of a given name?
需要注意的是,Unicode只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。
UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码(定长码),也是一种前缀码。它可以用来表示Unicode标准中的任何字符,且其编码中的第一个字节仍与ASCII兼容,这使得原来处理ASCII字符的软件无须或只须做少部份修改,即可继续使用。因此,它逐渐成为电子邮件、网页及其他存储或传送文字的应用中,优先采用的编码。互联网工程工作小组(IETF)要求所有互联网协议都必须支持UTF-8编码。
ValueError
Raised when a built-in operation or function receives an argument that has the right type but an inappropriate value, and the situation is not described by a more precise exception such as IndexError.
例如,str.index('\n')或者str.index('\n')。 如果str中没有'\n',那么raise ValueError
IndentationError
逐行读取文件
逐行读取,每行自带 '\n' !!!
利用迭代协议让for循环自动调用next从而前进到文件的下一行,而不是直接把文件读取到内存中,有三点原因:写法简单,运行速度快,节省内存。示例如下:
for line in open('myfile.py'):
...print line.upper()`
而不是使用readlines方法:
for line in open('myfile.py').readlines():
...print line.upper()`
with open(...) as f:
for line in f:
&do something with line&
The with statement handles opening and closing the file, including if an exception is raised in the inner block. The for line in f treats the file object f as an iterable, which automatically uses buffered IO and memory management so you don't have to worry about large files.
Garbage Collection
CPython 使用 mark-sweep & 分代回收
“标记-清除”法是为了解决循环引用问题。可以包含其他对象引用的容器对象(如list, dict, set,甚至class)都可能产生循环引用,为此,在申请内存时,所有容器对象的头部又加上了PyGC_Head来实现“标记-清除”机制。
在为对象申请内存的时候,可以明显看到,实际申请的内存数量已经加上了PyGC_Head的大小 (// objimpl.h, gcmodule.c)
一般来说,cmp和key可以使用lambda表达式。
sorted(L, cmp=lambda x,y:cmp(x[1],y[1]))
sorted(L, key=lambda x:x[1]))
sorted([5, 2, 3, 1, 4], reverse=True)
效率key&cmp(key比cmp快)
Regular Expression
alphanumerice
\W nonalphanumeric
re.search(pattern, string, flags=0)
Scan through string looking for the first location where the regular expression pattern produces a match, and return a corresponding MatchObject instance.
从字符串开头查找,只要子串符合就可以
re.match(pattern, string, flags=0)
从字符串开头比较,必须是从头开始的匹配
re.split(pattern, string, maxsplit=0, flags=0)
re.findall(pattern, string, flags=0)
Return all non-overlapping matches of pattern in string, as a list of strings.
re.sub(pattern, repl, string, count=0, flags=0)
re.sub('[^0-9a-zA-Z]+', '*', s) Replace all non-alphanumeric characters in a string
re.sub('\W+', '', s)
Functions&Utilities
Sort/Sorted
sorted函数是内建函数,他接受一个序列,返回有序的副本。他与sort的唯一区别就是会返回副本 (sorted is not in place!)
问题:如何根据一个字典序列中某一项的值,来对整个序列排序?
Python以引用方式管理对象,你可以交换引用,但通常不能交换内存中的对象值。当然你也不需要这样做。
a,b = b,a 即可
def swap(t1, t2):
t2, t1 = t1, t2
The code above does not do swap! 全局命名空间和局部命名空间是隔离的,所以:The calling namespace isnot changed,即交换的是局部变量。
def swap(a,b):
The code above does not do swap! 同样是因为局部namespace的隔离。
但是如果在主程序中:
tmp = swap_a
swap_a = swap_b
swap_b = tmp
则swap_a, swap_b 可以交换
使用timeit模块
使用time模块
+ Python的标准库手册推荐在任何系统下都尽量使用time.clock()(CPU时间)
System&Software
Interaction with the system
如何调用windows命令
os.system("dir")
!/usr/bin/python
If you have several versions of Python installed, /usr/bin/env will ensure the interpreter used is the first one on your environment's $PATH. The alternative would be to hardcode something like #!/usr/bin/ that's ok, but less flexible.
In Unix, an executable file that's meant to be interpreted can indicate what interpreter to use by having a #! at the start of the first line, followed by the interpreter (and any flags it may need).
Questions/Problems
多态?反射机制?Iterator&Generator?数据结构(set,dict, tuple)Decorators?内置函数,例如set___, __import等特殊的语句yield, with垃圾回收机制Decorators的定义,以及用法python线程机制以及为啥python多线程很慢。Errors and Exceptions
list = ['a', 'b', 'c', 'd', 'e']
print list[10:]
输出[],却不会引起IndexError错误
attempting to access a slice of a list at a starting index that exceeds the number of members in the list will not result in an IndexError and will simply return an empty list.
What makes this a particularly nasty gotcha is that it can lead to bugs that are really hard to track down since no error is raised at runtime.
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
选择支付方式:

我要回帖

更多关于 python iterable 的文章

 

随机推荐