更新到github了,地址:https://github.com/wklken/stackoverflow-py-top-qa
后续这里不更新了哈
进度40%,最近有点犯懒
刚刚注册,好东西
查看了下前面(vote前15页,挑了下,vote都是100+的样子,大概120个)的问题,链接, 大体梳理了下,本来想放一页搞定,奈何排版太乱,按类型分了下
第一页的前几个比较长,目测都有中文翻译版本,大家可以网上搜下
其他问题相对比较杂,有些简单,有些复杂,拉过来参考参考也不错
总结整理,复习印证(注意,合并了每个问题的多个答案,但是时间仓促,疏漏难免,感兴趣问题直接点链接看原文吧)
基本数据结构(列表,元组,字典等)判断一个列表为空得最佳实践
问题 链接
答案:
if not a: print "List is empty"#不要用len(a)来判断
为什么是string.join(list)而不是list.join(string)
问题 链接
my_list = ["Hello", "world"]print "-".join(my_list)#为什么不是 my_list.join("-") 。。。。这个....
答案:
因为所有可迭代对象都可以被连接,但是连接者总是字符串
如何合并两个列表
问题 链接
listone = [1,2,3]listtwo = [4,5,6]#outcome we expect: mergedlist == [1, 2, 3, 4, 5, 6]
1.不考虑顺序(原来问题不是很明确)
listone + listtwo#linstone.extend(listtwo)也行,就是会修改listone
2.考虑顺序做些处理
>>> listone = [1,2,3]>>> listtwo = [4,5,6]>>> import itertools>>> for item in itertools.chain(listone, listtwo):... print item...
如何扁平一个二维数组
问题 链接
l = [[1,2,3],[4,5,6], [7], [8,9]]变为[1, 2, 3, 4, 5, 6, 4, 5, 6, 7, 8, 9]
列表解析
[item for sublist in l for item in sublist]
itertools
>>> import itertools>>> list2d = [[1,2,3],[4,5,6], [7], [8,9]]>>> merged = list(itertools.chain(*list2d))# python >= 2.6>>> import itertools>>> list2d = [[1,2,3],[4,5,6], [7], [8,9]]>>> merged = list(itertools.chain.from_iterable(list2d))
sum
sum(l, [])
如何获取一个列表的长度
问题 链接
python中是不是只有这种方法可以获取长度?语法很奇怪
arr.__len__()
应该使用这种方式
mylist = [1,2,3,4,5]len(mylist)
这样做法,不需要对每个容器都定义一个.length()方法,你可以使用len()检查所有实现了__len__()方法的对象
Python中如何复制一个列表
问题 链接
可以用切片的方法
new_list = old_list[:]
可以使用list()函数
new_list = list(old_list)
可以使用copy.copy(),比list()稍慢,因为它首先去查询old_list的数据类型
import copynew_list = copy.copy(old_list)
如果列表中包含对象,可以使用copy.deepcopy(), 所有方法中最慢,但有时候无法避免
import copynew_list = copy.deepcopy(old_list)
例子:
import copyclass Foo(object): def __init__(self, val): self.val = val def __repr__(self): return str(self.val)foo = Foo(1)a = ['foo', foo]b = a[:]c = list(a)d = copy.copy(a)e = copy.deepcopy(a)# edit orignal list and instancea.append('baz')foo.val = 5print "original: %r\n slice: %r\n list(): %r\n copy: %r\n deepcopy: %r" \ % (a, b, c, d, e)
结果:
original: ['foo', 5, 'baz']slice: ['foo', 5]list(): ['foo', 5]copy: ['foo', 5]deepcopy: ['foo', 1]
效率简单比较
10.59 - copy.deepcopy(old_list)10.16 - pure python Copy() method copying classes with deepcopy1.488 - pure python Copy() method not copying classes (only dicts/lists/tuples)0.325 - for item in old_list: new_list.append(item)0.217 - [i for i in old_list] (a list comprehension)0.186 - copy.copy(old_list)0.075 - list(old_list)0.053 - new_list = []; new_list.extend(old_list)0.039 - old_list[:] (list slicing)
列表的append和extend的区别
问题 链接
>>> x = [1, 2]>>> x.append(3)>>> x[1, 2, 3]>>> x.append([4,5])>>> x[1, 2, 3, [4, 5]]>>>>>> x = [1, 2, 3]>>> x.extend([4, 5])>>> x[1, 2, 3, 4, 5]
如何随机地从列表中抽取变量
问题 链接
foo = ['a', 'b', 'c', 'd', 'e']from random import choiceprint choice(foo)
如何利用下标从列表中删除一个元素
问题 链接
1.del
In [9]: a = range(10)In [10]: aOut[10]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]In [11]: del a[-1]In [12]: aOut[12]: [0, 1, 2, 3, 4, 5, 6, 7, 8]
2.pop
a = ['a', 'b', 'c', 'd']a.pop(1)# now a is ['a', 'c', 'd']a = ['a', 'b', 'c', 'd']a.pop()# now a is ['a', 'b', 'c']
获取列表的最后一个元素
问题 链接
囧
result = l[-1]result = l.pop()
序列的切片操作
问题 链接
It’s pretty simple really:很简单:
a[start:end] # start 到 end-1a[start:] # start 到 末尾a[:end] # 0 到 end-1a[:] # 整个列表的拷贝
还有一个step变量,控制步长,可在上面语法中使用
a[start:end:step] # start through not past end, by step
注意,左闭右开
其他特点,开始或结束下标可能是负数,表示从序列末尾开始计算而非从头开始计算,所以
a[-1] # 最后一个元素a[-2:] # 最后两个元素a[:-2] # 除了最后两个元素
Python对程序员很友好,如果序列中存在的元素数量少于你要的,例如,你请求 a[:-2] 但是a只有一个元素,你会得到一个空列表,而不是一个错误.有时候你或许希望返回的是一个错误,所以你必须知道这点
如何将一个列表切分成若干个长度相同的子序列
问题 链接
想要得到这样的效果
l = range(1, 1000)print chunks(l, 10) -> [ [ 1..10 ], [ 11..20 ], .., [ 991..999 ] ]
使用yield:
def chunks(l, n): """ Yield successive n-sized chunks from l. """ for i in xrange(0, len(l), n): yield l[i:i+n]list(chunks(range(10, 75), 10))
直接处理
def chunks(l, n): return [l[i:i+n] for i in range(0, len(l), n)]
使用列表解析创建一个字典
问题 链接
python 2.6
d = dict((key, value) for (key, value) in sequence)
python 2.7+ or 3, 使用 字典解析语法
d = {key: value for (key, value) in sequence}
使用”in”还是”has_key()”
问题 链接
d = {'a': 1, 'b': 2}'a' in dTrueor:d = {'a': 1, 'b': 2}d.has_key('a')True
哪种更好
in更pythonic, 另外 has_key()在Python3.x中已经被移除
字典默认值
问题 链接
和问题有点偏
#获取时,如不存在,得到默认值d.get(key, 0)#设置时,若key不存在,设置默认值,已存在,返回已存在valued.setdefault(key, []).append(new_element)#初始即默认值from collections import defaultdictd = defaultdict(lambda: 0)#or d = defaultdict(int)
如何给字典添加一个值
问题 链接
#### Making a dictionary ####data = {}# OR #data = dict()#### Initially adding values ####data = {'a':1,'b':2,'c':3}# OR #data = dict(a=1, b=2, c=3)#### Inserting/Updating value ####data['a']=1 # updates if 'a' exists, else adds 'a'# OR #data.update({'a':1})# OR #data.update(dict(a=1))#### Merging 2 dictionaries ####data.update(data2) # Where data2 is also a dict.
如何将字段转换成一个object,然后使用对象-属性的方式读取
问题 链接
有dict
>>> d = {'a': 1, 'b': {'c': 2}, 'd': ["hi", {'foo': "bar"}]}}
想用这种方式访问
>>> x = dict2obj(d)>>> x.a>>> x.b.c>>> x.d[1].foobar
使用namedtuple
>>> from collections import namedtuple>>> MyStruct = namedtuple('MyStruct', 'a b d')>>> s = MyStruct(a=1, b={'c': 2}, d=['hi'])>>> sMyStruct(a=1, b={'c': 2}, d=['hi'])>>> s.a>>> s.b{'c': 2}>>> s.c>>> s.d['hi']
使用类
class Struct: def __init__(self, **entries): self.__dict__.update(entries)>>> args = {'a': 1, 'b': 2}>>> s = Struct(**args)>>> s<__main__.Struct instance at 0x01D6A738>>>> s.a>>> s.b
字符串,文件字符如何转为小写
问题 链接
s = "Kilometer"print(s.lower())
如何创建不存在的目录结构
问题 链接
if not os.path.exists(directory): os.makedirs(directory)
需要注意的是,当目录在exists和makedirs两个函数调用之间被创建时,makedirs将抛出OSError
如何拷贝一个文件
问题 链接
shutil模块
copyfile(src, dst)
将src文件内容拷贝到dst,目标文件夹必须可写,否则将抛出IOError异常
如果目标文件已存在,将被覆盖
另外特殊文件,想字符文件,块设备文件,无法用这个方法进行拷贝
src/dst是字符串
字符串转为float/int
>>> a = "545.2222">>> float(a)545.2222>>> int(a)Traceback (most recent call last):File "<stdin>", line 1, in <module>ValueError: invalid literal for int() with base 10: '545.2222'>>> int(float(a))>>> int('544')
另一种,用 ast模块
>>> import ast>>> ast.literal_eval("545.2222")545.2222>>> ast.literal_eval("31")
如何反向输出一个字符串
问题 链接
做法
>>> 'hello world'[::-1]'dlrow olleh'
如何随机生成大写字母和数字组成的字符串
6U1S75Z4UKKU911K4
解决
import string, random''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(N))
逐行读文件去除换行符(perl chomp line)
问题 链接类似问题 链接
读一个文件,如何获取每一行内容(不包括换行符)
比较pythonic的做法:
>>> text = "line 1\nline 2\r\nline 3\nline 4">>> text.splitlines()['line 1', 'line 2', 'line 3', 'line 4']
用rstrip,(rstrip/lstrip/strip)
#去除了空白+换行>>> 'test string \n'.rstrip()'test string'#只去换行>>> 'test string \n'.rstrip('\n')'test string '#更通用的做法,系统相关>>> import os, sys>>> sys.platform'linux2'>>> "foo\r\n".rstrip(os.linesep)'foo\r'
python中字符串的contains
问题 链接
python中字符串判断contains
使用in关键字
if not "blah" in somestring: continueif "blah" not in somestring: continue
使用字符串的find/index (注意index查找失败抛异常)
s = "This be a string"if s.find("is") == -1: print "No 'is' here!"else: print "Found 'is' in the string."
如何判断一个字符串是数字
问题 链接
使用这种方法会不会十分丑陋和低效
def is_number(s): try: float(s) return True except ValueError: return False
使用这种方法并不丑陋和低效
使用isdigit(缺点,对非整数无能为力)
a = "03523"a.isdigit()
如何填充0到数字字符串中保证统一长度
问题 链接
对于字符串
>>> n = '4'>>> print n.zfill(3)>>> '004'
对于数字,相关文档
>>> n = 4>>> print '%03d' % n>>> 004>>> print "{0:03d}".format(4) # python >= 2.6>>> 004>>> print("{0:03d}".format(4)) # python 3>>> 004
控制结构(条件、循环)如何在循环中获取下标
问题 链接
使用enumerate
for idx, val in enumerate(ints): print idx, val
如何判断一个变量的类型
问题 链接
使用type
>>> i = 123>>> type(i)<type 'int'>>>> type(i) is intTrue>>> i = 123456789L>>> type(i)<type 'long'>>>> type(i) is longTrue>>> i = 123.456>>> type(i)<type 'float'>>>> type(i) is floatTrue
另外一个相同的问题 链接
>>> type( [] ) == listTrue>>> type( {} ) == dictTrue>>> type( "" ) == strTrue>>> type( 0 ) == intTrue>>> class Test1 ( object ): pass>>> class Test2 ( Test1 ): pass>>> a = Test1()>>> b = Test2()>>> type( a ) == Test1True>>> type( b ) == Test2True>>> type( b ) == Test1False>>> isinstance( b, Test1 )True>>> isinstance( b, Test2 )True>>> isinstance( a, Test1 )True>>> isinstance( a, Test2 )False>>> isinstance( [], list )True>>> isinstance( {}, dict )True
类如何判断一个对象是否拥有某个属性
问题 链接
if hasattr(a, 'property'): a.property
两种风格
EAFP(easier to ask for forgiveness than permission)
LBYL(look before you leap)
相关内容EAFP vs LBYL (was Re: A little disappointed so far)EAFP vs. LBYL @Code Like a Pythonista: Idiomatic Python
try: doStuff(a.property)except AttributeError: otherStuff()orif hasattr(a, 'property'): doStuff(a.property)else: otherStuff()
Python中的类变量(环境变量)
问题 链接
在类中定义的变量,不在方法定义中,成为类变量或静态变量
>>> class MyClass:... i = 3...>>> MyClass.i
i是类级别的变量,但这里要和实例级别的变量i区分开
>>> m = MyClass()>>> m.i = 4>>> MyClass.i, m.i>>> (3, 4)
这和C++/java完全不同,但和C#区别不大,C#不允许类实例获取静态变量
具体见 what the Python tutorial has to say on the subject of classes and class objects
另外,静态方法
class C: @staticmethod def f(arg1, arg2, ...): ...
如何定义静态方法(static method)
问题 链接
使用 staticmethod装饰器
class MyClass(object): @staticmethod def the_static_method(x): print xMyClass.the_static_method(2) # outputs 2
@staticmethod和@classmethod的区别
问题 链接
staticmethod,静态方法在调用时,对类及实例一无所知
仅仅是获取传递过来的参数,没有隐含的第一个参数,在Python里基本上用处不大,你完全可以用一个模块函数替换它
classmethod, 在调用时,将会获取到其所在的类,或者类实例,作为其第一个参数
当你想将函数作为一个类工厂时,这非常有用: 第一个参数是类,你可以实例化出对应实例对象,甚至子类对象。
可以观察下 dict.fromkey(),是一个类方法,当子类调用时,返回子类的实例
>>> class DictSubclass(dict):... def __repr__(self):... return "DictSubclass"...>>> dict.fromkeys("abc"){'a': None, 'c': None, 'b': None}>>> DictSubclass.fromkeys("abc")DictSubclass>>>
如何获取一个实例的类名
问题 链接
x.__class__.__name__
模块如何列出一个目录的所有文件
问题 链接
1.使用os.listdir(),得到目录下的所有文件和文件夹
#只需要文件from os import listdirfrom os.path import isfile, joinonlyfiles = [ f for f in listdir(mypath) if isfile(join(mypath,f)) ]
2.os.walk()
from os import walkf = []for (dirpath, dirnames, filenames) in walk(mypath): f.extend(filenames) break
3.glob
import globprint glob.glob("/home/adam/*.txt")
重复问题 链接
import os
for dirname, dirnames, filenames in os.walk('.'): # print path to all subdirectories first. for subdirname in dirnames: print os.path.join(dirname, subdirname) # print path to all filenames. for filename in filenames: print os.path.join(dirname, filename)
json和simplejson的区别
问题 链接
json就是simple,加入到标准库. json在2.6加入,simplejson在2.4+,2.6+,更有优势
另外,simplejson更新频率更高,如果你想使用最新版本,建议用simplejson
好的做法是
try: import simplejson as jsonexcept ImportError: import json
另外,可以关注二者性能上的比较
python中如何获取当前时间
问题 链接
时间日期
>>> import datetime>>> datetime.datetime.now()datetime(2009, 1, 6, 15, 8, 24, 78915)
如果仅获取时间
>>> datetime.datetime.time(datetime.datetime.now())datetime.time(15, 8, 24, 78915))#等价>>> datetime.datetime.now().time()
可以从文档中获取更多 文档
如果想避免额外的datetime.
>>> from datetime import datetime
其他如何从标准输入读取内容stdin
问题 链接
使用fileinput
import fileinputfor line in fileinput.input(): pass
foo is None 和 foo == None的区别
问题 链接
if foo is None: passif foo == None: pass
如果比较相同的对象实例,is总是返回True而 == 最终取决于 “eq()”
>>> class foo(object): def __eq__(self, other): return True>>> f = foo()>>> f == NoneTrue>>> f is NoneFalse>>> list1 = [1, 2, 3]>>> list2 = [1, 2, 3]]>>> list1==list2True>>> list1 is list2False
另外
(ob1 is ob2) 等价于 (id(ob1) == id(ob2))
__init__.py是做什么用的
问题 链接
这是包的一部分,具体文档
__init__.py让Python把目录当成包,
最简单的例子,__init__.py仅是一个空文件,但它可以一样执行包初始化代码或者设置__all__变量,后续说明
如何获取安装的python模块列表
问题 链接
>>> help('modules')
环境相关setup.py安装后如何卸载
问题 链接
使用下面命令安装的包如何卸载
python setup.py install
手工删除的话
python setup.py install --record files.txtcat files.txt | xargs rm -rf
异常如何一行内处理多个异常
问题 链接
我知道可以这么做
try: # do something that may failexcept: # do this if ANYTHING goes wrong
也可以
try: # do something that may failexcept IDontLikeYourFaceException: # put on makeup or smileexcept YouAreTooShortException: # stand on a ladder
如果想在一行里处理多个异常的话
try: # do something that may failexcept IDontLIkeYouException, YouAreBeingMeanException: #没生效except Exception, e: #捕获了所有 # say please
答案
# as在python2.6,python2.7中仍然可以使用except (IDontLIkeYouException, YouAreBeingMeanException) as e: pass
如何flush Python的print输出
问题 链接重复问题 链接
默认print输出到sys.stdout
import syssys.stdout.flush()
参考http://docs.python.org/reference/simple_stmts.html#the-print-statementhttp://docs.python.org/library/sys.htmlhttp://docs.python.org/library/stdtypes.html#file-objects
如何获取一个函数的函数名字符串
问题 链接
my_function.__name__>>> import time>>> time.time.__name__'time'
应该在学习Python3之前学习Python2,还是直接学习Python3
问题 链接
你可以从python2开始,2和3主要的语法格式和风格相同
3要替代2不是短时间内能完成的,将会是一个很长的过程,所以学习Python2并没有什么坏处
我建议你关注下2和3的不同之处 This slides gives you a quick introduction of the changes in Python 2 and 3
python中用==比较字符串,is有时候会返回错误判断
问题 链接
is是身份测试,==是相等测试
>>> a = 'pub'>>> b = ''.join(['p', 'u', 'b'])>>> a == bTrue>>> a is bFalse'
is 等价于 id(a) == id(b)
如何截取一个字符串获得子串
问题 链接
>>> x = "Hello World!">>> x[2:]'llo World!'>>> x[:2]'He'>>> x[:-2]'Hello Worl'>>> x[-2:]'d!'>>> x[2:-2]'llo Worl'
python将这类操作称为切片,可以作用于序列类型,不仅仅是字符串
用函数名字符串调用一个函数
问题 链接
假设模块foo有函数bar:
import foomethodToCall = getattr(foo, 'bar')result = methodToCall()
或者一行搞定
result = getattr(foo, 'bar')()
如何获取文件扩展名
问题 链接
使用os.path.splitext方法:
>>> import os>>> fileName, fileExtension = os.path.splitext('/path/to/somefile.ext')>>> fileName'/path/to/somefile'>>> fileExtension'.ext'
如何获取list中包含某个元素所在的下标
问题 链接
>>> ["foo","bar","baz"].index('bar')
参照 文档
如何截掉空格(包括tab)
问题 链接
空白在字符串左右两边
s = " \t a string example\t "s = s.strip()
空白在字符串右边
s = s.rstrip()
左边
s = s.lstrip()
另外你可以指定要截掉的字符作为参数
s = s.strip(' \t\n\r')
如何将一个十六进制字符串转为整数
问题 链接
>>> int("a", 16)>>> int("0xa",16)
如何结束退出一个python脚本
问题 链接
import syssys.exit()
详细 文档
如何往文件中追加文本
问题 链接
with open("test.txt", "a") as myfile: myfile.write("appended text")
可以使用’a’或’a+b’ mode打开文件,见 文档
如何使用不同分隔符切分字符串
问题 链接
使用re.split 文档
>>> re.split('\W+', 'Words, words, words.')['Words', 'words', 'words', '']>>> re.split('(\W+)', 'Words, words, words.')['Words', ', ', 'words', ', ', 'words', '.', '']>>> re.split('\W+', 'Words, words, words.', 1)['Words', 'words, words.'])
或者匹配获取正确的 re.findall
import reDATA = "Hey, you - what are you doing here!?"print re.findall(r"[\w']+", DATA)# Prints ['Hey', 'you', 'what', 'are', 'you', 'doing', 'here']
如何获取一个字符的ASCII码
问题 链接
>>> ord('a')>>> chr(97)'a'>>> chr(ord('a') + 3)'d'>>>
另外对于unicode
>>> unichr(97)u'a'>>> unichr(1234)u'\u04d2'
排序一个列表中的所有dict,根据dict内值
问题 链接
如何排序如下列表,根据name或age
[{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}]
简单的做法;
newlist = sorted(list_to_be_sorted, key=lambda k: k['name'])
高效的做法
from operator import itemgetternewlist = sorted(list_to_be_sorted, key=itemgetter('name'))
读文件到列表中
问题 链接
f = open('filename')lines = f.readlines()f.close()等价with open(fname) as f: content = f.readlines()
文档
如何用http下载一个文件
问题 链接
直接使用urllib
import urlliburllib.urlretrieve ("http://www.example.com/songs/mp3.mp3", "mp3.mp3")
使用urllib2,并提供一个进度条
import urllib2url = "http://download.thinkbroadband.com/10MB.zip"file_name = url.split('/')[-1]u = urllib2.urlopen(url)f = open(file_name, 'wb')meta = u.info()file_size = int(meta.getheaders("Content-Length")[0])print "Downloading: %s Bytes: %s" % (file_name, file_size)file_size_dl = 0block_sz = 8192while True: buffer = u.read(block_sz) if not buffer: break file_size_dl += len(buffer) f.write(buffer) status = r"%10d [%3.2f%%]" % (file_size_dl, file_size_dl * 100. / file_size) status = status + chr(8)*(len(status)+1) print status,f.close()
使用第三方requests包
>>> import requests>>>>>> url = "http://download.thinkbroadband.com/10MB.zip">>> r = requests.get(url)>>> print len(r.content)
在virtualenv中如何使用不同的python版本
问题 链接
在创建virtualenv实例时,使用-p选项
virtualenv -p /usr/bin/python2.6 <path/to/new/virtualenv/>
python中如何将一行长代码切成多行
问题 链接
例如:
e = 'a' + 'b' + 'c' + 'd'变成e = 'a' + 'b' + 'c' + 'd'
括号中,可以直接换行
a = dostuff(blahblah1, blahblah2, blahblah3, blahblah4, blahblah5, blahblah6, blahblah7)
非括号你可以这么做
a = '1' + '2' + '3' + \ '4' + '5'或者a = ('1' + '2' + '3' + '4' + '5')
可以查看下代码风格: style guide推荐是后一种,但某些个别情况下,加入括号会导致错误
如何找到一个目录下所有.txt文件
问题 链接
使用glob
import globimport osos.chdir("/mydir")for files in glob.glob("*.txt"): print files
使用os.listdir
import osos.chdir("/mydir")for files in os.listdir("."): if files.endswith(".txt"): print files
或者遍历目录
import osfor r,d,f in os.walk("/mydir"): for files in f: if files.endswith(".txt"): print os.path.join(r,files)
如何使用绝对路径import一个模块
问题 链接
import impfoo = imp.load_source('module.name', '/path/to/file.py')foo.MyClass()
如何在遍历一个list时删除某些玄素
问题 链接
使用列表解析
somelist = [x for x in somelist if determine(x)]
上面那个操作将产生一个全新的somelist对象,而失去了对原有somelist对象的引用
#在原有对象上进行修改somelist[:] = [x for x in somelist if determine(x)]
使用itertools
from itertools import ifilterfalsesomelist[:] = list(ifilterfalse(determine, somelist))
如何强制使用浮点数除法
问题 链接
如何强制使除法结果c是浮点数
c = a / b
可以使用__future__
>>> from __future__ import division>>> a = 4>>> b = 6>>> c = a / b>>> c0.66666666666666663
或者转换,如果除数或被除数是浮点数,那么结果也是浮点数
c = a / float(b)
如何映射两个列表成为一个字典
问题 链接
两个列表
keys = ('name', 'age', 'food')values = ('Monty', 42, 'spam')
如何得到
dict = {'name' : 'Monty', 'age' : 42, 'food' : 'spam'}
使用zip
>>> keys = ['a', 'b', 'c']>>> values = [1, 2, 3]>>> dictionary = dict(zip(keys, values))>>> print dictionary{'a': 1, 'b': 2, 'c': 3}
找到当前目录及文件所在目录
问题 链接
查找当前目录使用os.getcwd()
查找某个文件的目录,使用, os.path
import os.pathos.path.realpath(__file__)
为何1 in [1,0] == True执行结果是False
问题 链接
有如下
>>> 1 in [1,0] # This is expectedTrue>>> 1 in [1,0] == True # This is strangeFalse>>> (1 in [1,0]) == True # This is what I wanted it to beTrue>>> 1 in ([1,0] == True) # But it's not just a precedence issue! # It did not raise an exception on the second example.Traceback (most recent call last): File "<pyshell#4>", line 1, in <module> 1 in ([1,0] == True) TypeError: argument of type 'bool' is not iterable
这里python使用了比较运算符链
in [1,0] == True
将被转为
(1 in [1, 0]) and ([1, 0] == True)
很显然是false的
同样的
a < b < c
会被转为
(a < b) and (b < c) # b不会被解析两次
具体文档
Python中的switch替代语法
问题 链接
python中没有switch,有什么推荐的处理方法么
使用字典:
def f(x): return { 'a': 1, 'b': 2, }.get(x, 9)
Python Cookbook中的几种方式
Readable switch construction without lambdas or dictionaries
Exception-based Switch-Case
Using a Dictionary in place of a ‘switch’ statement
如何将字符串转换为datetime
问题 链接
可以查看下time模块的strptime方法,反向操作是strftime
from datetime import datetimedate_object = datetime.strptime('Jun 1 2005 1:33PM', '%b %d %Y %I:%M%p')
扩展文档
Python中有没有简单优雅的方式定义单例类
问题 链接
我不认为有必要,一个拥有函数的模块(不是类)可以作为很好的单例使用,它的所有变量被绑定到这个模块,无论如何都不能被重复实例化
如果你确实想用一个类来实现,在python中不能创建私有类或私有构造函数,所以你不能隔离多个实例而仅仅通过自己的API来访问属性
我还是认为将函数放入模块,并将其作为一个单例来使用是最好的办法
将一个字符串转为一个字典
问题 链接
如何将字符串转成字典,不适用eval
s = "{'muffin' : 'lolz', 'foo' : 'kitty'}"
从python2.6开始,你可以使用内建模块 ast.literal_eval
>>> import ast>>> ast.literal_eval("{'muffin' : 'lolz', 'foo' : 'kitty'}"){'muffin': 'lolz', 'foo': 'kitty'}
这个做法比直接eval更安全帮助文档
>>> help(ast.literal_eval)Help on function literal_eval in module ast:literal_eval(node_or_string) Safely evaluate an expression node or a string containing a Python expression. The string or node provided may only consist of the following Python literal structures: strings, numbers, tuples, lists, dicts, booleans, and None.
举例
>>> eval("shutil.rmtree('mongo')")Traceback (most recent call last):File "<stdin>", line 1, in <module>File "<string>", line 1, in <module>File "/opt/Python-2.6.1/lib/python2.6/shutil.py", line 208, in rmtree onerror(os.listdir, path, sys.exc_info())File "/opt/Python-2.6.1/lib/python2.6/shutil.py", line 206, in rmtree names = os.listdir(path)OSError: [Errno 2] No such file or directory: 'mongo'>>> ast.literal_eval("shutil.rmtree('mongo')")Traceback (most recent call last):File "<stdin>", line 1, in <module>File "/opt/Python-2.6.1/lib/python2.6/ast.py", line 68, in literal_eval return _convert(node_or_string)File "/opt/Python-2.6.1/lib/python2.6/ast.py", line 67, in _convert raise ValueError('malformed string')ValueError: malformed string
Python如何检查一个对象是list或者tuple,但是不是一个字符串
问题 链接
原来的做法是
assert isinstance(lst, (list, tuple))
有没有更好的做法
我认为下面的方式是你需要的
assert not isinstance(lst, basestring)
原来的方式,你可能会漏过很多像列表,但并非list/tuple的
使用 ‘if x is not None’ 还是’if not x is None’
问题 链接
我总想着使用 ‘if x is not None’ 会更加简明
但是google的Python风格指南使用的却是 ‘if x is not None’
性能上没有什么区别,他们编译成相同的字节码
Python 2.6.2 (r262:71600, Apr 15 2009, 07:20:39)>>> import dis>>> def f(x):... return x is not None...>>> dis.dis(f) 0 LOAD_FAST 0 (x) 3 LOAD_CONST 0 (None) 6 COMPARE_OP 9 (is not) 9 RETURN_VALUE>>> def g(x):... return not x is None...>>> dis.dis(g) 0 LOAD_FAST 0 (x) 3 LOAD_CONST 0 (None) 6 COMPARE_OP 9 (is not) 9 RETURN_VALUE
在风格上,我尽量避免 ‘not x is y’ 这种形式,虽然编译器会认为和 ‘not (x is y)’一样,但是读代码的人或许会误解为 ‘(not x) is y’
如果写作 ‘x is not y’ 就不会有歧义
最佳实践
if x is not None: # Do something about x
如何获取一个文件的创建和修改时间
问题 链接
跨平台的获取文件创建及修改时间的方法
你有很多选择
使用os.path.getmtime或者os.path.getctime
import os.path, timeprint "last modified: %s" % time.ctime(os.path.getmtime(file))print "created: %s" % time.ctime(os.path.getctime(file))
或者os.stat
import os, time(mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime) = os.stat(file)print "last modified: %s" % time.ctime(mtime)
注意,ctime()并非指*nix系统中文件创建时间,而是这个节点数据的最后修改时间
如何离开virtualenv
问题 链接
使用virtualenv时
me@mymachine:~$ workon env1(env1)me@mymachine:~$ workon env2(env2)me@mymachine:~$ workon env1(env1)me@mymachine:~$
如何退出某个环境
$ deactivate
如何认为地抛出一个异常
问题 链接
pythonic
raise Exception("I know python!")
更多可参考 文档
在Python中如何展示二进制字面值
问题 链接
十六进制可以
>>> 0x12AF>>> 0x100
八进制可以
>>> 01267>>> 0100
二进制如何表示?
Python 2.5 及更早版本: 可以表示为 int(‘01010101111’,2) 但没有字面量
Python 2.6 beta: 可以使用0b1100111 or 0B1100111 表示
Python 2.6 beta: 也可以使用 0o27 or 0O27 (第二字字符是字母 O)
Python 3.0 beta: 同2.6,但不支持027这种语法
Python中检查类型的权威方法
问题 链接
检查一个对象是否是给定类型或者对象是否继承于给定类型?
比如给定一个对象o,如何判断是不是一个str
检查是否是str
type(o) is str
检查是否是str或者str的子类
isinstance(o, str)
下面的方法在某些情况下有用
issubclass(type(o), str)type(o) in ([str] + str.__subclasses__())
注意,你或许想要的是
isinstance(o, basestring)
因为unicode字符串可以满足判定(unicode 不是str的子类,但是str和unicode都是basestring的子类)
可选的,isinstance可以接收多个类型参数,只要满足其中一个即True
isinstance(o, (str, unicode))
如何获取Python的site-packages目录位置
问题 链接
参考 How to Install Django” documentation
可以在shell中执行
python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())"
更好的可读性
from distutils.sysconfig import get_python_libprint(get_python_lib())
Python中*和的作用
问题 链接
args和*kwargs允许函数拥有任意数量的参数,具体可以查看 more on defining functions
*args将函数所有参数转为序列
In [1]: def foo(*args):...: for a in args:...: print a...:...:In [2]: foo(1)In [4]: foo(1,2,3)
**kwargs 将函数所有关键字参数转为一个字典
In [5]: def bar(**kwargs):...: for a in kwargs:...: print a, kwargs[a]...:...:In [6]: bar(name="one", age=27)age 27name one
两种用法可以组合使用
def foo(kind, *args, **kwargs): pass
*l的另一个用法是用于函数调用时的参数列表解包(unpack)
In [9]: def foo(bar, lee):...: print bar, lee...:...:In [10]: l = [1,2]In [11]: foo(*l) 2
在Python3.0中,可以将*l放在等号左边用于赋值 Extended Iterable Unpacking
first, *rest = [1,2,3,4]first, *l, last = [1,2,3,4]
字符串格式化 % vs format
问题 链接
Python2.6中引入string.format()方法,语法和原先%操作符的字符串格式化差异较大
在什么情况下使用哪种更好?
以下的输出是一致的,有什么区别
#!/usr/bin/pythonsub1 = "python string!"sub2 = "an arg"a = "i am a %s"%sub1b = "i am a {0}".format(sub1)c = "with %(kwarg)s!"%{'kwarg':sub2}d = "with {kwarg}!".format(kwarg=sub2)print aprint bprint cprint d
.format 看起来更加强大,可以用在很多情况.
例如你可以在格式化时重用传入的参数,而你用%时无法做到这点
另一个比较讨厌的是,%只处理 一个变量或一个元组, 你或许会认为下面的语法是正确的
"hi there %s" % name
但当name恰好是(1,2,3)时,会抛出TypeError异常.为了保证总是正确的,你必须这么写
"hi there %s" % (name,) # supply the single argument as a single-item tuple
这么写很丑陋, .format没有这些问题
什么时候不考虑使用.format
你对.format知之甚少使用Python2.5
Python中什么项目结构更好
问题 链接
假设你要开发一个较大的客户端程序(非web端),如何组织项目目录和递归?
不要太在意这个.按你高兴的方式组织就行.Python项目很简单,所以没有那么多愚蠢的规则
/scripts or /bin 命令行脚本/tests 测试/lib C-语言包/doc 文档/apidoc api文档
并且顶层目录包含README和Config
难以抉择的是,是否使用/src树. /src,/lib,/bin在Python中没有明显的区别,和Java/c不同
因为顶层/src文件夹显得没有什么实际意义,你的顶层目录可以是程序顶层架构的目录
/foo/bar/baz
我建议将这些文件放入到”模块名”的目录中,这样,如果你在写一个应用叫做quux, /quux目录将包含所有这些东西
你可以在PYTHONPATH中加入 /path/to/quux/foo,这样你可以QUUX.foo中重用模块
另一个回答
Project/|-- bin/| |-- project||-- project/| |-- test/| | |-- __init__.py| | |-- test_main.py| || |-- __init__.py| |-- main.py||-- setup.py|-- README
argparse可选位置参数
问题 链接
脚本运行 usage: installer.py dir [-h] [-v]
dir是一个位置参数,定义如下
parser.add_argument('dir', default=os.getcwd())
我想让dir变为可选,如果未设置,使用os.getcwd()
不幸的是,当我不指定dir时,得到错误 “Error: Too few arguments”
尝试使用 nargs=’?’
parser.add_argument('dir', nargs='?', default=os.getcwd())
例子
>>> import os, argparse>>> parser = argparse.ArgumentParser()>>> parser.add_argument('-v', action='store_true')_StoreTrueAction(option_strings=['-v'], dest='v', nargs=0, const=True, default=False, type=None, choices=None, help=None, metavar=None)>>> parser.add_argument('dir', nargs='?', default=os.getcwd())_StoreAction(option_strings=[], dest='dir', nargs='?', const=None, default='/home/vinay', type=None, choices=None, help=None, metavar=None)>>> parser.parse_args('somedir -v'.split())Namespace(dir='somedir', v=True)>>> parser.parse_args('-v'.split())Namespace(dir='/home/vinay', v=True)>>> parser.parse_args(''.split())Namespace(dir='/home/vinay', v=False)>>> parser.parse_args(['somedir'])Namespace(dir='somedir', v=False)>>> parser.parse_args('somedir -h -v'.split())usage: [-h] [-v] [dir]positional arguments:diroptional arguments:-h, --help show this help message and exit-v
Python中 new 和 __init__的用法
问题 链接
我很疑惑,为何__init__总是在__new__之后调用
如下
class A(object): _dict = dict() def __new__(cls): if 'key' in A._dict: print "EXISTS" return A._dict['key'] else: print "NEW" return super(A, cls).__new__(cls) def __init__(self): print "INIT" A._dict['key'] = self print ""a1 = A()a2 = A()a3 = A()
输出
NEWINITEXISTSINITEXISTSINIT
有木有人可以解释一下
来自 链接
使用__new__,当你需要控制一个实例的生成
使用__init__,当你需要控制一个实例的初始化
__new__是实例创建的第一步.最先被调用,并且负责返回类的一个新实例.
相反的,__init__不返回任何东西,只是负责在实例创建后进行初始化
通常情况下,你不必重写__new__除非你写一个子类继承不可变类型,例如str,int,unicode或tuple
你必须了解到,你尝试去做的用Factory可以很好地解决,并且是最好的解决方式.使用__new__不是一个简洁的处理方式,一个factory例子
Python ‘self’ 解释
问题 链接
self关键字的作用是什么?我理解他用户在创建class时具体化实例,但我无法理解为何需要给每个方法加入self作为参数.
举例,在ruby中,我这么做:
class myClass def myFunc(name) @name = name endend
我可以很好地理解,非常简单.但是在Python中,我需要去加入self:
class myClass: def myFunc(self, name): self.name = name
有谁能解释下么?
使用self关键字的原因是,Python没有@语法用于引用实例属性.Python决定用一种方式声明方法:实例对象自动传递给属于它的方法,但不是接收自动化:方法的第一个参数是调用这个方法的实例对象本身.这使得方法整个同函数一致,并且由你自己决定真实的名(虽然self是约定,但当你使用其他名的时候,通常人们并不乐意接受).self对于代码不是特殊的,只是另一个对象.
Python本来可以做一些用来区分真实的名字和属性的区别 —— 像Ruby有的特殊语法,或者像C++/Java的命令声明,或者其他可能的的语法 —— 但是Python没有这么做.Python致力于使事情变得明确简单,让事情是其本身,虽然并不是全部地方都这么做,但是实例属性石这么做的!这就是为什么给一个实例属性赋值时需要知道是给哪个实例赋值,并且,这就是为什么需要self
举例
class Vector(object): def __init__(self, x, y): self.x = x self.y = y def length(self): return math.sqrt(self.x ** 2 + self.y ** 2)
等价于
def length_global(vector): return math.sqrt(vector.x ** 2 + vector.y ** 2)
另外
v_instance.length()转为Vector.length(v_instance)
为什么Python的’private’方法并不是真正的私有方法
问题 链接
Python允许我们创建’private’ 函数:变量以两个下划线开头,像这样: __myPrivateMethod().但是,如何解释:
>>> class MyClass:... def myPublicMethod(self):... print 'public method'... def __myPrivateMethod(self):... print 'this is private!!'...>>> obj = MyClass()>>> obj.myPublicMethod()public method>>> obj.__myPrivateMethod()Traceback (most recent call last):File "", line 1, inAttributeError: MyClass instance has no attribute '__myPrivateMethod'>>> dir(obj)['_MyClass__myPrivateMethod', '__doc__', '__module__', 'myPublicMethod']>>> obj._MyClass__myPrivateMethod()this is private!!
dir(obj) 和 obj._MyClass__myPrivateMethod()
回答
‘private’只是用作,确保子类不会意外覆写父类的私有方法和属性.不是为了保护外部意外访问而设计的!
例如:
>>> class Foo(object):... def __init__(self):... self.__baz = 42... def foo(self):... print self.__baz...>>> class Bar(Foo):... def __init__(self):... super(Bar, self).__init__()... self.__baz = 21... def bar(self):... print self.__baz...>>> x = Bar()>>> x.foo()>>> x.bar()>>> print x.__dict__{'_Bar__baz': 21, '_Foo__baz': 42}
当然,这对于两个同名的类没有作用
另外,可以查看diveintopython的解释 入口
Python中类方法的作用是什么
问题 链接
我现在意识到,我不需要像我在使用java的static方法那样使用类方法,但是我不确定什么时候使用
谁能通过一个好的例子解释下Python中的类方法,至少有人能告诉我什么时候确实需要使用类方法
类方法用在:当你需要使用不属于任何明确实例的方法,但同时必须涉及类.有趣的是,你可以在子类中覆写,这在Java的static方法和Python的模块级别函数中是不可能做到的
如果你有一个MyClass, 并且一个模块级别函数操作MyClass(工厂,依赖注入桩等等), 声明一个类方法.然后这个类方法可以在子类中调用
如何删除一个list中重复的值同时保证原有顺序
问题 链接
我是这么做的额
def uniq(input):output = []for x in input: if x not in output: output.append(x)return output
有什么更好的方法?
你可以在这里找到一些可用的方法 入口
最快的一个
def f7(seq): seen = set() seen_add = seen.add return [ x for x in seq if x not in seen and not seen_add(x)]
如果你需要在同一个数据集中多次是哦那个这个方法,或许你可以使用ordered set处理 http://code.activestate.com/recipes/528878/
插入,删除和归属判断复杂度都是O(1)
有什么方法可以获取系统当前用户名么?
问题 链接
至少在Linux和Windows下都可用.就像 os.getuid
>>> os.getuid()>>> os.getusername()'slartibartfast'
可以看看 getpass 模块
>>> import getpass>>> getpass.getuser()'kostya'
可用: Unix, Windows
Python assert最佳实践
问题 链接
有没有代码实例使用assert作为独立代码,而不是仅用来debug
assert x >= 0, 'x is less than zero'类似if x < 0: raise Exception, 'x is less than zero'有什么方法,可以设定一个规则就像 if x \&; 0 抛出错误但是不是通过try/except/finally检查的
搞晕了:
原文 Also, is there any way to set a business rule like if x \&; 0 raise error that is always checked without the try/except/finally so, if at anytime throughout the code x is less than 0 an error is raised, like if you set assert x < 0 at the start of a function, anywhere within the function where x becomes less then 0 an exception is raised?
回答
Assert仅用在,测试那些从不发生的情况!目的是让程序尽早失败
Exception用在,那些可以明确知道会发生的错误,并且建议总是创建自己的异常类
例如,你写一个函数从配置文件中读取配置放入字典,文件格式不正确抛出一个ConfigurationSyntaxError,同时你可以assert返回值非None
在你的例子中,如果x是通过用户接口或外部传递设置的,最好使用exception
如果x仅是同一个程序的内部代码,使用assert
在非创建全局变量的地方使用全局变量
问题 链接
如果我在一个函数中创建了全局变量,如何在另一个函数中使用?
回答:
你可以在给全局变量赋值的函数中声明 global
globvar = 0def set_globvar_to_one(): global globvar # Needed to modify global copy of globvar globvar = 1def print_globvar(): print globvar # No need for global declaration to read value of globvarset_globvar_to_one()print_globvar() # Prints 1
我猜想这么做的原因是,全局变量很危险,Python想要确保你真的知道你要对一个全局的变量进行操作
如果你想知道如何在模块间使用全局变量,查看其他回答
如何在单一表达式中合并两个Python字典
问题 链接
>>> x = {'a':1, 'b': 2}>>> y = {'b':10, 'c': 11}>>> z = x.update(y)>>> print zNone>>> x{'a': 1, 'b': 10, 'c': 11}
我想要最终合并结果在z中,不是x,我要怎么做?
回答
这种情况下,可以使用
z = dict(x.items() + y.items())
这个表达式将会实现你想要的,最终结果z,并且相同key的值,将会是y中key对应的值
>>> x = {'a':1, 'b': 2}>>> y = {'b':10, 'c': 11}>>> z = dict(x.items() + y.items())>>> z{'a': 1, 'c': 11, 'b': 10}
如果在Python3中,会变得有些复杂
>>> z = dict(list(x.items()) + list(y.items()))>>> z{'a': 1, 'c': 11, 'b': 10}
如何使用 pip 更新所有包
问题 链接
如何使用pip更新python的所有包
没有内置的标志可以实现
但是你可以这么做
pip freeze --local | grep -v '^\-e' | cut -d = -f 1 | xargs pip install -U
Python中声明exception的方法
问题 链接
在python2.6中定义异常得到警告
>>> class MyError(Exception):... def __init__(self, message):... self.message = message...>>> MyError("foo")_sandbox.py:3: DeprecationWarning: BaseException.message has been deprecated as of Python 2.6
问题很长,大意如标题
回答
或许我理解错了,但是为什么不这样做
class MyException(Exception): pass
如果要重写什么,例如传递额外参数,可以这么做
class ValidationError(Exception): def __init__(self, message, Errors): # Call the base class constructor with the parameters it needs Exception.__init__(self, message) # Now for your custom code... self.Errors = Errors
你可以通过第二个参数传递error 字典, 之后通过e.Errors获取
在Python中使用Counter错误
问题 链接
当使用Counter时,出现异常
AttributeError: 'module' object has no attribute 'Counter'from collections import CounterImportError: cannot import name Counter
原因:
版本问题,Counter在 python2.7中才被加入到这个模块,你可能使用了Python2.6或更老的版本
可以看下 文档
如果要在 Python2.6或2.5版本使用,可以看 这里
如何删除Python easy_install安装的包
问题 链接
pip, setuptools/easy_install的另一种选择,提供uninstall命令
首先,移除依赖
$ easy_install -m [PACKAGE]
然后,手动删除egg文件
$ rm -rf .../python2.X/site-packages/[PACKAGE].egg
在Python中如何解析xml
问题 链接
<foo><bar> <type foobar="1"/> <type foobar="2"/></bar></foo>
如何解析获取xml文件中内容
我建议使用 ElementTree (有其他可用的实现,例如 lxml,他们只是更快, ElementTree提供更简单的编程api)
在使用XML建立Element实例之后,例如使用 XML 函数
for atype in e.findall('type') print(atype.get('foobar'))
如何将一个Python time.struct_time对象转换为一个datetime对象
问题 链接
使用 time.mktime() 将time元组(本地时间)转成秒, 然后使用 datetime.fromtimestamp() 转成datetime对象
from time import mktimefrom datetime import datetimedt = datetime.fromtimestamp(mktime(struct))