溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

分享Python 的十個小技巧

發(fā)布時間:2020-07-23 14:04:38 來源:網(wǎng)絡 閱讀:692 作者:nineteens 欄目:編程語言

  一. 列表、字典、集合、元組的使用

  from random import randint, sample

  # 列表解析

  data = [randint(-10, 10) for _ in xrange(10)]

  filter(lambda x: x >= 0, data)

  [x for x in data if x >= 0] #最快速

  # 字典解析

  d = {x: randint(60, 100) for x in xrange(1,21)}

  {k : v for k, v in d.iteritems() if v > 90}

  # 集合解析

  s = set(data)

  {x for x in s if x % 3 ==0}

  # 元組

  student = ('Jim', 16, 'male', 'jim@qq.com')

  # 1. enum

  NAME, AGE, SEX, EMAIL = xrange(4)

  print student[NAME]

  # 2.

  from collections import namedtuple

  Student = namedtuuple('Student', ['name', 'age', 'sex', 'email'])

  s2 = Student('Tom', 16, 'mail', 'tom@qq.com')

  print s2.name

  # 統(tǒng)計列表的重復元素

  li = [randint(0, 20) for _ in xrange(30)]

  d = dict.fromkeys(li, 0)

  # 1.

  for x in li: d[x] += 1

  # 2.

  from collections import Counter

  d2 = Counter(li)

  d2.most_common(3) #重復數(shù)最高的三個元素

  # 字典根據(jù)值value排序

  sorted([3, 1, 5]) #排序列表

  (97, 'a') > (88, 'b') # 元組的比較,每個元素從開始比較

  d = {x: randint(60, 100) for x in 'abcde'}

  # 1.

  data = zip(d.itervalues(), d.iterkeys())

  sorted(data)

  # 2.

  sorted(d.items(), key=lambda x: x[1])

  # 多個字典中的公共鍵

  sample('abcdefg', 3)

  sample('abcdefg', randint(3,6)) # 隨機取出幾個元素

  s1 = {x: randint(1,4) for x in sample('abcdefg', randint(3.6))}

  s2 = {x: randint(1,4) for x in sample('abcdefg', randint(3.6))}

  s3 = {x: randint(1,4) for x in sample('abcdefg', randint(3.6))}

  # 1.

  res = []

  for k in s1: if k in s2 and k in s3: res.append(k) # res.pop(k)

  # 2. 使用集合

  res = s1.viewkeys() & s2.viewkeys() & s3.viewkeys()

  # 3.

  m1 = map(dict.viewkeys, [s1, s2, s3])

  res = reduce(lambda a, b: a & b, m1)

  # 保持字典有序

  d = {'Jim':(1, 35), 'Leo':(2, 38), 'Tom':(3, 44)}

  from collections import OrderedDict

  d = OrderedDict() #按進入字典的順序打印

  d['Jim'] = (1,35)

  d['Leo'] = (2,38)

  d['Tom'] = (3,44)

  from time import time

  start = time()

  raw_input() #等待輸入

  # ...

  timesecond = time() - start

  # 歷史記錄

  # 1. 用隊列存儲

  from collections import deque

  q = deque([], 5)

  q.append(1) # 達到長度后,先進先出

  li = list(q) # 轉(zhuǎn)換成列表類型

  # 2. 將q存到文件中

  import pickle

  pickle.dump(q, open('test','w'))

  q2 = pickle.load(open('test','r'))

  二. 迭代器、生成器

  # 實現(xiàn)可迭代對象、迭代器對象

  # 用時訪問 并封裝到一個對象中

  # 可迭代對象

  li = [1,2,3,4]

  str= 'abcde'

  # 迭代器

  iterl = iter(li) # li.__iter__()

  iters = iter(str) # str.__getitem__()

  iterl.next()

  # 1. 城市天氣的迭代器和可迭代對象

  from collections import Iterable, Iterator

  class WIterator(Iterator):

  def __init__(self, cities):

  self.cities = cities

  self.index = 0

  def getWeather(city):

  import requests

  r = requests.get(u'http://wthrcdn.etouch.cn/weather_mini?city=' + city)

  data = r.json()['data']['forecast'][0]

  return '%s: %s, %s' % (city, data['low'], data['high'])

  def next(self):

  if self.index == len(self.cities)

  raise StopIteration

  city = self.cities[self.index]

  self.index += 1

  return self.getWeather(city)

  class WIterable(Iterable):

  def __init__(self, cities):

  self.cities = cities

  def __iter__(self):

  return WIterator(self.cities)

  for x in WIterable([u'北京', u'長沙', u'廣州']):

  print x

  # 2. 使用生成器函數(shù)實現(xiàn)可迭代對象

  def f():

  print 'in f(), 1'

  yield 1

  print 'in f(), 2'

  yield 2

  g = f() # g.__iter__()

  for i in g: print i

  class PrintNumbers:

  def __init__(self, start, end):

  self.start = start

  self.end = end

  def isPrimeNum(self, k):

  if k % 2 == 0:

  return True

  else:

  return False

  def __iter__(self):

  for k in xrange(self.start, self.end+1):

  if self.isPrimeNum(k):

  yield k

  for x in PrintNumbers(1, 100): print x

  # 進行反向迭代

  li = [1,2,3,4,5]

  li.reverse() # 改變原來列表

  li[::-1] # 切片,和原來列表等大的新列表

  ll = li.reversed(li) # 列表反向迭代

  for i in ll: print i

  class FloatRange:

  def __init__(self, start, end, step=0.1)

  self.start = start

  self.end = end

  self.step = step

  def __iter__(self):

  t = self.start

  while t <= self.end:

  yield t

  t += self.step

  def __reversed__(self):

  t = self.enf

  while t >= self.start:

  yield t

  t -= self.step

  # 正向迭代

  for i in FloatRange(1.0, 4.0, 0.5): print x

  # 反向迭代

  for i in reversed(FloatRange(1.0, 4.0, 0.5)): print x

  # 對迭代器做切片操作

  from itertools import islice

  # islice()

  li = range(20)

  t = iter(li)

  for x in islice(t, 5, 10): print x # 會消耗原來的迭代對象

  # 在一個for中迭代多個可迭代對象

  chinese = [randint(60,100) for _ in xrange(40)]

  math = [randint(60,100) for _ in xrange(40)]

  english = [randint(60,100) for _ in xrange(40)]

  for in in xrange(len(math)):

  print chinese[i] + math[i] + english[i]

  total = []

  # 并行多個可迭代對象

  for c, m, e in zip(chiness, math, english)

  print c+m+e

  # 1. 串連多個迭代對象

  from itertools import chain

  c1 = [randint(60,100) for _ in xrange(40)]

  c2 = [randint(60,100) for _ in xrange(42)]

  c3 = [randint(60,100) for _ in xrange(45)]

  for s in chain(c1, c2, c3):

  if s > 90: print s

  三. 字符串

  # 拆分含多種分隔符的字符串

  s = "fwerf sd123 ^sdf dfdsf*d dsf 123"

  s.split(“xy”) #默認以空格分割,或以參數(shù)分割

  res = s.split(";")

  map(lambda x: x.split("|"), res) # 以";"和"|"分割的二維數(shù)組

  t = []

  map(lambda x: t.extend(x.split("|")), res) # 二維元素放到t中

  # 1.

  def aSplit(s, ds):

  res = [s]

  for d in ds:

  t = []

  map(lambda x: t.extend(x.split(d)), res)

  res = t

  return res

  print aSplit(s, " ^*") # 會存在空的元素

  # 2. 正則表達式

  import re

  re.split(r'[,;|]+', s)

  # 判斷字符串a(chǎn)是否以b開頭或結(jié)尾

  #s.startswith() s.endswith() 接收單個字符串或字符串元組

  import os, stat

  files = [name for name in os.listdir(".") if name.endswith(('.sh', '.py'))]

  # 調(diào)整字符串中文本的格式

  #日志中'yyyy-mm-dd' 改為 'mm/dd/yyyy'

  import re

  log = open("/var/log/dpkg.log").read()

  re.sub('(\d{4})-(\d{2})-(\d{2})', r'\2/\3/\1', log)

  re.sub('(?P\d{4})-(?P\d{2})-(?P\d{2})', r'\g/\g/\g', log)

  # 多個小字符串拼接成大字符串

  s1 = "abcde"

  s2 = "12345"

  s1 + s2 # str.__add__(s1, s2) str.__gt__(s1, s2) 運算符重載

  s = ""

  for p in pl: s += p # 變量多時,臨時變量開銷大,資源浪費

  s.join(s1) # 參數(shù)可為字符串,可為列表

  li = ['avc', 123, 'xyz', 456]

  ''.join([str(x) for x in li]) #列表解析,會生成一個列表,開銷大

  ''.join(str(x) for x in li) #生成器, (str(x) for x in li) 作為參數(shù)是括號省略

  # 字符串格式對齊

  # str.ljust() str.rjust() str.center()

  s = "abc"

  s.ljust(10 ,'=') # 左對齊,填充=

  s.center(10)

  format(s, '<20') # 左對齊

  format(s, '>20') # 右對齊

  format(s, '^20') # 居中

  # 去掉字符串中不需要的字符

  s = ' -------sd dfadf 2332 +++++++++'

  s.strip(' -+')

  s.lstrip()

  s.rstirp()

  # 刪除固定位置的字符,拼接切片

  s[:3]+ s[4:]

  # 替換

  s.replace('\t', '')

  import re

  re.sub('[\t\r]', '', s)

  s = 'abc123e3rxyz'

  #s.translate()

  import string

  tr = string.maketrans('abcxyz', 'xyzabc')

  s.translate(tr)

  s = 'abc\rdfd\n234234\t'

  s.translate(None, '\r\t\n')

  四. 文件讀寫

  # python2 str unicode

  # python3 bytes str

  # python2

  s = u'你好'

  s.encode('utf8') #存儲到文件中的格式

  f = open('hello.txt', 'w')

  f.write(s.encode('utf8'))

  f.close()

  f = open('hello.txt', 'r')

  t = f.read().decode('utf8') # 你好

  f.close()

  # python3 字符串就是unicode

  strb = b'asdfasdfsdg'

  s = '你好'

  f = open('hello2.txt', 'wt', encoding='utf8') # 自動完成編解碼

  f.write(s)

  f.close()

  f = open('hello2.txt', 'rt', encoding='utf8')

  s = f.read()

  f.close()

  # 處理二進制文件 處理音頻文件,將音量調(diào)小保存

  f = open('demo.wav', 'rb')

  info = f.read(44) #文件頭

  import struct

  struct.unpack('h',info[22:24]) #處理文件頭 數(shù)據(jù)運算

  struct.unpack('i',infi[24:28])

  f.seek(0,2)

  f.tell()

  n = (f.tell()-44) /2

  import array

  buf = array.array('h', (0 for _ in xrange(n)))

  f.seek(44)

  f.readinto(buf)

  for i in xrange(n): buf[i] /= 8

  f2 = open('demo2.wav', 'wb')

  f2.write(info)

  buf.tofile(f2)

  f2.close()

  # 使用臨時文件

  # 自動刪除,不占內(nèi)存

  from tempfile import TemporaryFile, NamedTemporaryFile

  f = TemporaryFile() # 系統(tǒng)文件系統(tǒng)找不到

  f.write('abcddee'*100000)

  f.seek(0)

  f.read(100)

  ntf = NamedTemporaryFile(delete=False) # 能找到文件,默認關閉以后會刪除文件

  fname = nft.name

  # 設置文件的緩沖

  # I/O 操作以塊為單位,如4096字節(jié)一個塊

  f = open('test.txt', 'w', buffering=2048) # 全緩沖,要寫滿緩沖才會寫到文件中

  f = open('test.txt', 'w', buffering=1) # 行緩沖,\n就會寫文件

  f = open('test.txt', 'w', buffering=1) # 無緩沖,實時寫

  f.write('abc')

  # 將文件映射到內(nèi)存

  import mmap

  f = open('demo.bn','r+b')

  f.fileno()

  m = mmap.mmap(f.fileno(), 0, access=mmpa.ACCESS_WRITE, offset=mmap.PAGESIZE)

  # 得到字節(jié)數(shù)組

  m[4:8] = '\xff'*4 # 修改直接改變文件內(nèi)容

  # 讀寫csv數(shù)據(jù)

  from urllib import urlretrieve

  urlretrieve('http://table.finance.yahoo.com/table.csv?s=000001.sz', 'pingan.csv')

  rf = open('pingan.csv', 'rb')

  import csv

  reader = csv.reader(rf)

  header = reader.next()

  wf = open('pingan_c.csv', 'wb')

  writer = csv.writeer(wf)

  writer.writerow(header)

  rf.close()

  wf.close()

  # 讀寫json數(shù)據(jù)

  import requests

  import json

  from record import Record

  record = Record(channel=1)

  audioData = record.record(2)

  from secret import API_KEY, SECRET_KEY

  authUrl = "https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=" + API_KEY + "&client_secret=" + SECRET_KEY

  response = requests.get(authUrl)

  res = json.loads(response.content)

  token = res['access_token']

  #百度語音識別

  cuid = 'xxxxxxxxxxxxx'

  srvUrl = 'http://vop.baidu.com/server_api?cuid=' + cuid + '&token=' + token

  heepHeader = {'Content-Type': 'audio/wav; rate = 8000'}

  response = requests.post(srvUrl, headers=httpHeader, data=audioData)

  res = json.loads(response.content)

  text = res['result'][0]

  print text

  # json.dumps() python對象(列表、字典等)轉(zhuǎn)換成json字符串

  # json.dumps(data, sort_keys=True)

  # json.loads() json字符串轉(zhuǎn)換成python對象

  with open('demo.json', 'wb') as f:

  json.dump(l, f) # 將l數(shù)據(jù)寫到文件

  # 構(gòu)建xml文檔

  from xml.etree.ElementTree import parse

  with open('demo.xml') with f:

  et = parse(f)

  root = et.getroot()

  root.tag

  root.attrib

  root.text

  #root.getchildren()

  for child in root:

  print child.get('name')

  root.find('country')

  root.findall('country') # 直接子元素

  for e in root.iterfind('country'):

  print e.get('name')

  from xml.etree.ElementTree import Element, ElementTree, tostring

  e = Element('Data')

  e.set('name', 'abc')

  e2 = Element('Row')

  e3 = Element('Open')

  e3.text = '8.80'

  e2.append(e3)

  e.append(e2)

  tostring(e)

  et = ElementTree(e)

  et.write('demo.xml')

  # 讀寫excel文件

  import xlrd, xlwt

  book = xlrd.open_workbook('demo.xls')

  book.sheets()

  sheet = book.sheet_by_index(0)

  rows = sheet.nrows

  cols = sheet.ncols

  cell = sheet.cell(0,0) #(0,0)單元格

  cell.ctype

  cell.value

  row = sheet.row(1) #cell對象列表

  data = sheet.row_values(1, 1) #第1列跳過第一格的值列表

  sheet.put_cell(0, cols, xlrd.XL_CELL_TEXT, u'Total', None)

  wbook = xlwt.Workbook()

  wsheet = wbook.add_sheet('sheet1')

  style = xlwt.easyxf('align: vertical center, horizontal center')

  wsheet.write(rows,cols, sheet.cell_value(rows,cols), style)

  wsheet.save('output.xls')

  五. 派生內(nèi)置不可變類型并修改其實例化行為

  class IntTuple(tuple):

  def __new__(cls, iterable): #先于__init__()調(diào)用

  g = (x for x in iterable if isinstance(x, int) and x > 0)

  super(IntTuple, cls).__new__(cls, g)

  def __init__(self, iterable):

  # 此時如果過濾iterable 無法過濾成功

  super(IntTuple, self).__init__(iterable)

  t = IntTuple([1, -1, 'abc', 6, ['x', 'y'], 3])

  print t?無錫婦科醫(yī)院排名 http://www.csyhjlyy.com/

  六. 使用描述符對實例屬性做類型檢查

  # 描述符: 包含 __get__() __set__() __delete__() 函數(shù)的類

  class Attr(object):

  def __init__(self, name, type_):

  self.name = name

  self.type_= type_

  def __get__(self, instance, cls):

  return instanse.__dict__[self.name]

  def __set__(self, instance, value):

  if not isinstance(value, self.type_):

  raise TypeError('expected %s' % self.type_)

  instance.__dict__[self.name] = value

  def __delete__(self, instance):

  del instance.__dict__[self.name]

  class Person(object):

  name = Attr('name', str)

  age = Attr('age', int)

  hgt = Attr('height', float)

  p = Person()

  p.name = 'Bob'

  print p.name

  p.age = '17' #會拋出異常

  七. 在環(huán)狀數(shù)據(jù)結(jié)構(gòu)中管理內(nèi)存

  import sys

  class A(object):

  def __del__(self): # 當引用次數(shù)變?yōu)?時,調(diào)用析構(gòu)函數(shù)

  print 'in A.__del__'

  a = A()

  a2 = a

  print sys.getrefcount(a) - 1 # 查看對象a的引用次數(shù),參數(shù)名也引用了對象,要-1

  del a

  del a2

  # 循環(huán)引用

  class Data(object): # Data類保存Node對象引用

  def __init__(self, value, owner):

  self.owner = owner

  self.value = value

  def __str__(self):

  return "%s's data, value is %s" % (self.owner, self.value)

  def __del__(self):

  print 'in Data.__del__'

  class Node(object): # Node類調(diào)用Data對象

  def __init__(self, valu):

  self.data = Data(value, self)

  def __del__(self):

  print 'in Node.__del__'

  node = Node(100)

  del node # 此時Data Node不會被回收掉

  raw_input('wait...')

  # 使用弱引用

  import weakref

  a_wref = weakref.ref(a)

  a2 = a_wref()

  class Data(object): # Data類保存Node對象引用

  def __init__(self, value, owner):

  self.owner = weakref.ref(owner) # 弱引用

  self.value = value

  def __str__(self):

  return "%s's data, value is %s" % (self.owner(), self.value)

  def __del__(self):

  print 'in Data.__del__'

  node2 = node(100)

  del node2 # 此時Data Node將被回收

  八. 通過實例方法名的字符串調(diào)用方法

  # Circle Triangle Trctangle 求面積的方法名都不同

  # 通過傳方法名來調(diào)用不同的方法

  # 1. getattr 獲取對象屬性,方法名也是屬性

  from lib1 import Circle

  from lib2 import Triangle

  from lib3 import Tectangle

  def getArea(shape):

  for name in ('area', 'getArea', get_area):

  f = getattr(shape, name , None)

  if f:

  return f()

  shape1 = Circle(2)

  shape2 = Tirangle(3,4,5)

  shape3 = Rectangle(6,4)

  shapes = [shape1, shape2, shape3]

  print map(getArea, shapes)

  # 2. 使用opreator標準庫

  from opreator import methodcaller

  s = "abc123abc456"

  s.find('abc', 4)

  methodcaller('find', 'abc', 4)(s)

  九. 為創(chuàng)建大量實例節(jié)省內(nèi)存

  class Player(object):

  def __init__(self, uid, name, status=0, level=1):

  self.uid = uid

  self.name = name

  self.stat = status

  self.level = level

  class Player2(object):

  __slots__ = ['uid', 'name', 'stat', 'level']

  def __init__(self, uid, name, status=0, level=1):

  self.uid = uid

  self.name = name

  self.stat = status

  self.level = level

  p1 = Player('0001', 'Jim')

  p2 = Player2('0002', 'Tom')

  # p1 bi p2 多兩個屬性 __dict__ __weakref__

  # __dict__ 字典,為實例動態(tài)綁定解除新屬性

  # p2 則不能動態(tài)綁定屬性

  # __slots__ 阻止了該功能

  十. 讓對象支持上下文管理

  # 要使用上下文管理,類中要定義 __enter__ __exit__方法,分別在with開始和結(jié)束時調(diào)用

  class test(object):

  ...

  def __enter__(self):

  pass

  def __exit__(self, exc_type, exc_val, exc_tb):

  pass

  with test() as k:

  pass


向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI