[翻译整理]stackoverflow python 百问

更新到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))
[翻译整理]stackoverflow python 百问

相关文章:

你感兴趣的文章:

标签云: