python高級操作以及常見問題解決辦法

0.快速工程化

  • Streamlit 第三方工具

判斷python系統版本

  • if sys.version_info.major == 2:

udp socket

  • 端口是通過端口號來標記的,端口號只有整數,範圍是從0到65535
  • 知名端口是衆所周知的端口號,範圍從0到1023
    • 80端口分配給HTTP服務
    • 21端口分配給FTP服務
  • 用“netstat -an”查看端口狀態
  • 利用ip地址,協議,端口就可以標識網絡的進程了,網絡中的進程通信就可以利用這個標誌與其它進程進行交互
    • 所謂進程間通信指的是:運行的程序之間的數據共享,socket(簡稱 套接字) 是進程間通信的一種方式

Structure of the Examples/示例結構

  • 依據values 獲取鍵
lis = {1:"a",2:"b"}
 list(lis.keys())[list(lis.values()).index('a')]

python進階

lambda

  • lambda表達式是一行函數。
    • lambda 參數:操作(參數)
add = lambda x,y:x+y
print(add(3,5))
  • 排序列表
data = zip(list1,list2)
data.sort()
list1,list2 = map(lambda t:list(t),zip(*data))

異常

try:
    file = open('test.txt', 'rb')
except IOError as e:
    print('An IOError occurred. {}'.format(e.args[-1]))
else:
    # 這裏的代碼只會在try語句裏沒有觸發異常時運行,
    # 但是這裏的異常將 *不會* 被捕獲
    print('This would only run if no exception occurs. And an error here would NOT be caught.')
finally:
    print("This would be printed whether or not an exception")

*args **kwargs

  • 函數定義的時候,將不定數量的參數傳遞給一個函數。
  • *args 是非鍵值對參數元組
# *argv 非鍵值對的參數,個數不限制
def test_var_args(f_arg, *argv):
    print("first normal arg:", f_arg)
    print(argv,type(argv))
    for arg in argv:
        print("another arg through *argv:", arg)
test_var_args('yasoob', 'python', 'eggs', 'test')
  • **kwags 允許你將不定長度的鍵值對作爲參數的傳遞給函數
def greet_me(**kwargs):
    for key, value in kwargs.items():
    print("{0} == {1}".format(key, value))
greet_me(name="yasoob")
#name == yasoob

生成器

  • 在for循環中增加一個yeild 關鍵詞就是生成器

map filter reduce

  • map將一個函數應用到輸入的所有列表元素
    • map(func_name,list_inputs)
    • list(map(lambda x:x**2,lists)
  • filter 過濾列表中的元素,返回符合要求的新列表
number_list = range(-5,5)
new_list = filter(lambda x:x<0,number_list)
  • reduce
from functools import reduce
product = reduce( (lambda x, y: x * y), [1, 2, 3, 4] )
# 24 int 

三元運算符

condition = True
print(2 if condition else 1/0)

減少內存

  • python類的實例屬性,默認是存儲在字典中,佔用內存比較大;使用__slots__來告訴python不要使用字典,使用列表存儲屬性。
class MyClass(object):
    __slots__ = ['name', 'identifier'] 
    def __init__(self, name, identifier):
        self.name = name 
        self.identifier = identifier 
        self.set_up()

deque 雙端隊列

from collections import deque
d = deque()
d.append(1)
d.append(2)
d.append(3)
print(len(d))
d = deque(range(5))
print(len(d))
print(d.popleft())
print(d.pop())
print(d)

字典推導式 集合推導式

  • 字典鍵值對換
{v:k for k,v in some_dict.items()}
  • 字典推導式
mcase = {'a': 10, 'b': 34, 'A': 7, 'Z': 3}
mcase_frequency = { k.lower(): mcase.get(k.lower(), 0) + mcase.get(k.upper(),0) for k in mcase.keys()}
# mcase_frequency == {'a': 17, 'z': 3, 'b': 34}
  • 集合推導式
squared = {x**2 for x in [1, 1, 2]} 
print(squared)

python3 改爲默認的python 版本

sudo update-alternatives --install /usr/bin/python python /usr/bin/python2 100
sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 150

如果要切換到Python2,執行:
sudo update-alternatives --config python

python多線程與多進程的區別

1、多線程可以共享全局變量,多進程不能
2、多線程中,所有子線程的進程號相同;多進程中,不同的子進程進程號不同
3、線程共享內存空間;進程的內存是獨立的
4、同一個進程的線程之間可以直接交流;兩個進程想通信,必須通過一箇中間代理來實現
5、創建新線程很簡單;創建新進程需要對其父進程進行一次克隆
6、一個線程可以控制和操作同一進程裏的其他線程;但是進程只能操作子進程
兩者最大的不同在於:在多進程中,同一個變量,各自有一份拷貝存在於每個進程中,互不影響;而多線程中,所有變量都由所有線程共享 。

bash

  • hash brownie指一種含有大麻成分的蛋糕, 所以這裏是句雙關

1.

some_dict = {}
some_dict[5.5] = "Ruby"
some_dict[5.0] = "JavaScript"
some_dict[5] = "Python"

Output:

>>> some_dict[5.5]
"Ruby"
>>> some_dict[5.0]
"Python"
>>> some_dict[5]
"Python"

裝飾器

  • 在代碼運行期間動態增加功能的方式,稱之爲“裝飾器”(Decorator)

python 高級編程

  • 類就是一組用來描述如何生成對象的代碼段
class ObjectCreator(object)
    pass
- ObjectCreator其實也是一種變量,你可以將它複製給一個變量
- 可以拷貝,可以增加屬性,可以將它作爲函數參數進行傳遞
- 類也是對象,可以在運行的時候動態的創建,就像其他任何對象一樣。

元類

  • 元類就是創建類的東西
  • 元類就是類的類,type就是元類
  • python中所有的東西,都是對象:整數、字符串、函數和類

迭代器

  • 迭代器是一種訪問集合元素的方式。迭代器是一個可以記住遍歷的位置的對象。迭代器對象從集合的第一個元素開始訪問,直接到所有的元素被訪問完結束。迭代器智能往前不能後退。
    • 迭代對象
      • 一類是集合數據類型:set list tuple dict str
      • 一類是生成器:generator,包含生成器和帶yield的generator function對象
        這些都是直接可以用於for循環的可迭代對象,Iterable
  • 判斷是否可以迭代的方法
from collections import Iterable
isinstance([],Iterable) # true
isinstance((),Iterable) # true
isinstance({},Iterable) # true
isinstance('abc',Iterable) # true
isinstance((x for x in range(5)),Iterable) # true
  • 判斷是否是迭代器
from collections import Iterator

isinstance([],Iterator) # False
isinstance((),Iterator) # False
isinstance({},Iterator) # False
isinstance('abc',Iterator) # False
isinstance((x for x in range(5)),Iterator) # True
  • 雖然list stuple dict str 雖然是可以迭代的,但不是迭代器。
  • 把list dict str等轉化爲迭代器可以使用iter()
isinstance(iter([]),Iterator) # True
isinstance(iter('abc'),Iterator) #True
  • 凡是可以作用於for循環的對象都是Iterable類型
  • 凡是可以用於next()函數的都是Iterator類型
  • 集合數據類型list、dict、str等都是Iterable但不是Iterator,不過可以通過iter()函數獲取一個Iterator對象。

python 速查表

常規

  • Python 對大小寫敏感
  • Python 的索引從 0 開始
  • Python 使用空白符(製表符或空格)來縮進代碼,而不是使用花括號

獲取幫助

  • 獲取主頁幫助:help()
  • 獲取函數幫助:help(str.replace)
  • 獲取模塊幫助:help(re)

模塊(庫)

Python的模塊只是一個簡單地以 .py 爲後綴的文件。

  • 列出模塊內容:dir(module1)
  • 導入模塊:import module
  • 調用模塊中的函數:module1.func1()

import語句會創建一個新的命名空間(namespace),並且在該命名空間內執行.py文件中的所有語句。如果你想把模塊內容導入到當前命名空間,請使用from module1 import *語句。

數值類類型

查看變量的數據類型:type(variable)

六種經常使用的數據類型

  1. int/long:過大的 int 類型會被自動轉化爲 long 類型

  2. float:64 位,Python 中沒有 double 類型

  3. bool:真或假

  4. str:在 Python 2 中默認以 ASCII 編碼,而在 Python 3 中默認以 Unicode 編碼

    • 字符串可置於單/雙/三引號中

    • 字符串是字符的序列,因此可以像處理其他序列一樣處理字符串

    • 特殊字符可通過 \ 或者前綴 r 實現:

      str1 = r'this\f?ff'
      
    • 字符串可通過多種方式格式化:

      template = '%.2f %s haha $%d';
      str1 = template % (4.88, 'hola', 2)
      
  5. NoneType(None):Python “null”值(None對象存在一個實例)

    • None不是一個保留關鍵字,而是NoneType的一個唯一實例

    • None通常是可選函數參數的默認值:

      def func1(a, b, c=None)
      
    • None的常見用法:

      if variable is None :
      
  6. datetime:Python內置的datetime模塊提供了datetimedata以及time類型。

    • datetime組合了存儲於datetime中的信息
    # 從字符串中創建 datetime
    dt1 = datetime.strptime('20091031', '%Y%m%d')
    # 獲取 date 對象
    dt1.date()
    # 獲取 time 對象
    dt1.time()
    # 將 datetime 格式化爲字符串
    dt1.strftime('%m/%d/%Y%H:%M')
    # 更改字段值
    dt2 = dt1.replace(minute=0, second=30)
    # 做差, diff 是一個 datetime.timedelta 對象
    diff = dt1 - dt2
    

  • strboolintfloat同時也是顯式類型轉換函數。
  • 除字符串和元組外,Python 中的絕大多數對象都是可變的。

數據結構

:所有的“非只讀(non-Get)”函數調用,比如下面例子中的list1.sort(),除非特別聲明,都是原地操作(不會創建新的對象)。

元組

元組是 Python 中任何類型的對象的一個一維、固定長度、不可變的序列。

# 創建元組
tup1 = 4, 5, 6
tup1 = (6, 7, 8)
# 創建嵌套元組
tup1 = (4, 5, 6), (7, 8)
# 將序列或迭代器轉化爲元組
tuple([1, 0, 2])
# 連接元組
tup1 + tup2
# 解包元組
a, b, c = tup1

元組應用

# 交換兩個變量的值
a, b = b, a

列表

列表是 Python 中任何類型的對象的一個一維、非固定長度、可變(比如內容可以被修改)的序列。

# 創建列表
list1 = [1, 'a', 3]
list1 = list(tup1)
# 連接列表
list1 + list2
list1.extend(list2)
# 追加到列表的末尾
list1.append('b')
# 插入指定位置
list1.insert(PosIndex, 'a')
# 反向插入,即彈出給定位置的值/刪除
ValueAtIdx = list1.pop(PosIndex)
# 移除列表中的第一個值, a 必須是列表中第一個值
list1.remove('a')
# 檢查成員
3 in list1 => True or False
# 對列表進行排序
list1.sort()
# 按特定方式排序
list1.sort(key=len) # 按長度排序
  • 使用 + 連接列表會有比較大的開支,因爲這個過程中會創建一個新的列表,然後複製對象。因此,使用extend()是更明智的選擇。
  • insertappend相比會有更大的開支(時間/空間)。
  • 在列表中檢查是否包含一個值會比在字典和集合中慢很多,因爲前者需要進行線性掃描,而後者是基於哈希表的,所以只需要花費常數時間。

內置的bisect模塊

  • 對一個排序好的列表進行二分查找或插入

  • bisect.bisect找到元素在列表中的位置,bisect.insort將元素插入到相應位置。

  • 用法:

    import bisect
    list1 = list(range(10))
    #找到 5 在 list1 中的位置,從 1 開始,因此 position = index + 1
    bisect.bisect(list1, 5)
    #將 3.5 插入 list1 中合適位置
    bisect.insort(list1, 3.5)
    

bisect 模塊中的函數並不會去檢查列表是否排序好,因爲這會花費很多時間。所以,對未排序好的列表使用這些函數也不會報錯,但可能會返回不正確的結果。

針對序列類型的切片

序列類型包括strarraytuplelist等。

用法:

list1[start:stop]
# 如果使用 step
list1[start:stop:step]

  • 切片結果包含 start 索引,但不包含 stop 索引
  • start/stop 索引可以省略,如果省略,則默認爲序列從開始到結束,如 list1 == list1[:]

step 的應用:

# 取出奇數位置的元素
list1[::2]
# 反轉字符串
str1[::-1]

字典(哈希表)

# 創建字典
dict1 = {'key1': 'value1', 2: [3, 2]}
# 從序列創建字典
dict(zip(KeyList, ValueList))
# 獲取/設置/插入元素
dict1['key1']
dict1['key1'] = 'NewValue'
# get 提供默認值
dict1.get('key1', DefaultValue)
# 檢查鍵是否存在
'key1' in dict1
# 獲取鍵列表
dict1.keys()
# 獲取值列表
dict1.values()
# 更新值
dict1.update(dict2)  # dict1 的值被 dict2 替換
  • 如果鍵不存在,則會出現 KeyError Exception
  • 當鍵不存在時,如果 get()不提供默認值則會返回 None
  • 以相同的順序返回鍵列表和值列表,但順序不是特定的,也就是說極大可能非排序。

有效字典鍵類型

  • 鍵必須是不可變的,比如標量類型(intfloatstring)或者元組(元組中的所有對象也必須是不可變的)。
  • 這兒涉及的技術術語是“可哈希(hashability)”。可以用函數hash()來檢查一個對象是否是可哈希的,比如 hash('This is a string')會返回一個哈希值,而hash([1,2])則會報錯(不可哈希)。

集合

  • 一個集合是一些無序且唯一的元素的聚集;

  • 你可以把它看成只有鍵的字典;

    # 創建集合
    set([3, 6, 3])
    {3, 6, 3}
    # 子集測試
    set1.issubset(set2)
    # 超集測試
    set1.issuperset(set2)
    # 測試兩個集合中的元素是否完全相同
    set1 == set2
    
  • 集合操作

    • 並(或):set1 | set2
    • 交(與):set1 & set2
    • 差:set1 - set2
    • 對稱差(異或):set1 ^ set2

函數

Python 的函數參數傳遞是通過引用傳遞

  • 基本形式

    def func1(posArg1, keywordArg1=1, ..)
    

    • 關鍵字參數必須跟在位置參數的後面;
    • 默認情況下,Python 不會“延遲求值”,表達式的值會立刻求出來。
  • 函數調用機制

    1. 所有函數均位於模塊內部作用域。見“模塊”部分。
    2. 在調用函數時,參數被打包成一個元組和一個字典,函數接收一個元組args和一個字典kwargs,然後在函數內部解包。
  • “函數是對象”的常見用法:

    def func1(ops = [str.strip, user_define_func, ..], ..):
        for function in ops:
            value = function(value)
    

返回值

  • 如果函數直到結束都沒有return語句,則返回None

  • 如果有多個返回值則通過一個元組來實現。

    return (value1, value2)
    value1, value2 = func1(..)
    

匿名函數(又稱 LAMBDA 函數)

  • 什麼是匿名函數?

    匿名函數是一個只包含一條語句的簡單函數。

    lambda x : x * 2
    # def func1(x) : return x * 2
    
  • 匿名函數的應用:“柯里化(curring)”,即利用已存在函數的部分參數來派生新的函數。

    ma60 = lambda x : pd.rolling_mean(x, 60)
    

一些有用的函數(針對數據結構)

  1. Enumerate 返回一個序列(i, value)元組,i 是當前 item 的索引。

    for i, value in enumerate(collection):
    
    • 應用:創建一個序列中值與其在序列中的位置的字典映射(假設每一個值都是唯一的)。
  2. Sorted 可以從任意序列中返回一個排序好的序列。

    sorted([2, 1, 3]) => [1, 2, 3]
    
    • 應用:

      sorted(set('abc bcd')) => [' ', 'a', 'b', 'c', 'd']
      # 返回一個字符串排序後無重複的字母序列
      
  3. Zip 函數可以把許多列表、元組或其他序列的元素配對起來創建一系列的元組。

    zip(seq1, seq2) => [('seq1_1', 'seq2_1'), (..), ..]
    
    • zip()可以接收任意數量的序列作爲參數,但是產生的元素的數目取決於最短的序列。

    • 應用:多個序列同時迭代:

      for i, (a, b) in enumerate(zip(seq1, seq2)):
      
    • unzip:另一種思考方式是把一些行轉化爲一些列:

      seq1, seq2 = unzip(zipOutput)
      
  4. Reversed 將一個序列的元素以逆序迭代。

    list(reversed(range(10)))
    

    reversed() 會返回一個迭代器,list() 使之成爲一個列表。

控制流

  1. 用於 if-else 條件中的操作符:

    var1 is var2  # 檢查兩個變量是否是相同的對象
    
    var1 is not var2  # 檢查兩個變量是否是不同的對象
    
    var1 == var2  # 檢查兩個變量的值是否相等
    

    :Python 中使用 andornot 來組合條件,而不是使用 &&||!

  2. for循環的常見用法:

    for element in iterator:  # 可迭代對象(list、tuple)或迭代器
        pass
    
    for a, b, c in iterator:  # 如果元素是可以解包的序列
        pass
    
  3. pass:無操作語句,在不需要進行任何操作的塊中使用。

  4. 三元表達式,又稱簡潔的 if-else,基本形式:

    value = true-expr if condition else false-expr
    
  5. Python 中沒有 switch/case 語句,請使用 if/elif

面向對象編程

  1. 對象是 Python 中所有類型的根。

  2. 萬物(數字、字符串、函數、類、模塊等)皆爲對象,每個對象均有一個“類型(type)”。對象變量是一個指向變量在內存中位置的指針。

  3. 所有對象均會被引用計數

    sys.getrefcount(5) => x
    a = 5, b = a
    # 上式會在等號的右邊創建一個對象的引用,因此 a 和 b 均指向 5
    sys.getrefcount(5)
    => x + 2
    del(a); sys.getrefcount(5) => x + 1
    
  4. 類的基本形式:

    class MyObject(object):
        # 'self' 等價於 Java/C++ 中的 'this'
        def __init__(self, name):
            self.name = name
        def memberFunc1(self, arg1):
            pass
        @staticmethod
        def classFunc2(arg1):
            pass
    obj1 = MyObject('name1')
    obj1.memberFunc1('a')
    MyObject.classFunc2('b')
    
  5. 有用的交互式工具:

    dir(variable1)  # 列出對象的所有可用方法
    

常見字符串操作

# 通過分隔符連接列表/元組
', '.join([ 'v1', 'v2', 'v3']) => 'v1, v2, v3'

# 格式化字符串
string1 = 'My name is {0} {name}'
newString1 = string1.format('Sean', name = 'Chen')

# 分裂字符串
sep = '-';
stringList1 = string1.split(sep)

# 獲取子串
start = 1;
string1[start:8]

# 補 '0' 向右對齊字符串
month = '5';
month.zfill(2) => '05'
month = '12';
month.zfill(2) => '12'
month.zfill(3) => '012'

異常處理

  1. 基本形式:

    try:
        pass
    except ValueError as e:
        print e
    except (TypeError, AnotherError):
        pass
    except:
        pass
    finally:
        pass  # 清理,比如 close db;
    
  2. 手動引發異常:

    raise AssertionError  # 斷言失敗
    raise SystemExit
    # 請求程序退出
    raise RuntimeError('錯誤信息 :..')
    

列表、字典以及元組的推導表達式

使代碼更加易讀易寫的語法糖。

  1. 列表推導

    • 用一個簡練的表達式,通過篩選一個數據集並且轉換經過篩選的元素的方式來簡明地生成新列表。

    • 基本形式:

      [expr for val in collection if condition]
      

    等價於

    result = []
    for val in collection:
        if condition:
            result.append(expr)
    

    可以省略過濾條件,只留下表達式。

  2. 字典推導

    • 基本形式:

      {key-expr : value-expr for value in collection if condition}
      
  3. 集合推導

    • 基本形式:和列表推導一樣,不過是用 () 而不是 []
  4. 嵌套列表

    • 基本形式:

      [expr for val in collection for innerVal in val if condition]
      

單元測試

Python自帶unittest模塊,可供我們編寫單元測試。

import unittest

我們可以編寫繼承於unittest.TestCase測試類的子類,並在子類中編寫具體的測試函數。測試函數命必須以test_開頭,否則不會被識別爲測試函數,進而不會在運行單元測試時被運行。

class TestSubclass(unittest.TestCase):

    def test_func(self):
        self.assertEqual(0, 0)
        # 可以通過msg關鍵字參數提供測試失敗時的提示消息
        self.assertEqual(0, 0, msg='modified message')
        self.assertGreater(1, 0)
        self.assertIn(0, [0])
        self.assertTrue(True)
        # 測試是否會拋出異常
        with self.assertRaises(KeyError):
            _ = dict()[1]

    # 被@unittest.skip裝飾器裝飾的測試類或測試函數會被跳過
    @unittest.skip(reason='just skip')
    def test_skip(self):
        raise Exception('I shall never be tested')

另外,unittest.TestCase中還有兩個特殊的成員函數,他們分別會在調用每一個測試函數的前後運行。在測試前連接數據庫並在測試完成後斷開連接是一種常見的使用場景。

def setUp(self):
    # To do: connect to the database
    pass

def tearDown(self):
    # To do: release the connection
    pass

def test_database(self):
    # To do: test the database
    pass

測試類編寫完畢後,可以通過添加以下代碼來將當前文件當成正常的Python腳本使用

if __name__ == '__main__':
  unittest.main()

打印重定向

with open('./work/test.txt', 'wt') as f:
    print('Hello World!', file=f)

元組或者序列值解壓賦值給N個變量

  • 任何的序列(或者是可迭代對象)可以通過一個簡單的賦值操作來分解爲單獨的變量。 唯一的要求就是變量的總數和結構必須與序列相吻合。
name, shares, price, (year, mon, day) = [ 'ACME', 50, 91.1, (2012, 12, 21) ]
name, shares, price, date = [ 'ACME', 50, 91.1, (2012, 12, 21) ]

解壓可迭代對象賦值給多個變量

  • Python 的星號表達式可以用來解決這個問題
def drop_first_last(grades):
    first, *middle, last = grades
    return avg(middle)
    
    
record = ('Dave', '[email protected]', '773-555-1212', '847-555-1212')
name, email, *phone_numbers = record

保留最後N個元素

  • 保留有限歷史記錄正是 collections.deque 大顯身手的時候 ,核心思想:先進先出
from collections import deque
q = deque(maxlen=3)  # deque([1, 2, 3], maxlen=3)
q.append(4)  # deque([2, 3, 4], maxlen=3)

查找最大或最小的N個元素

import heapq
nums = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2]
print(heapq.nlargest(3, nums)) # Prints [42, 37, 23]
print(heapq.nsmallest(3, nums)) # Prints [-4, 1, 2]
  • 兩個函數都能接受的一個關鍵字參數
portfolio = [
    {'name': 'IBM', 'shares': 100, 'price': 91.1},
    {'name': 'AAPL', 'shares': 50, 'price': 543.22},
    {'name': 'FB', 'shares': 200, 'price': 21.09},
    {'name': 'HPQ', 'shares': 35, 'price': 31.75},
    {'name': 'YHOO', 'shares': 45, 'price': 16.35},
    {'name': 'ACME', 'shares': 75, 'price': 115.65}
]
cheap = heapq.nsmallest(3, portfolio, key=lambda s: s['price'])
expensive = heapq.nlargest(3, portfolio, key=lambda s: s['price'])

堆數據結構

  • 堆數據結構最重要的特徵是 heap[0] 永遠是最小的元素。並且剩餘的元素可以很容易的通過調用 heapq.heappop() 方法得到, 該方法會先將第一個元素彈出來,然後用下一個最小的元素來取代被彈出元素(這種操作時間複雜度僅僅是 O(log N),N 是堆大小)
import heapq
nums = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2]
heap = list(nums)
heaps = heapq.heapify(heap)
print(heaps,type(heaps),heap,type(heap))

for i in range(5):
    last = heapq.heappop(heap)
    print('last',last)
    i += 1

字典中鍵映射多個值

  • 值要放在set或者list裏面
from collections import defaultdict

d = defaultdict(list)
d['a'].append(1)
d['a'].append(2)
d['b'].append(4)

d = defaultdict(set)
d['a'].add(1)
d['a'].add(2)
d['b'].add(4)

d = defaultdict(list)
for key, value in pairs:
    d[key].append(value)

字典排序

  • 使用collections 模塊的OrderDict類.在迭代的時候保持被插入時的順序。
from collections import OrderedDict

d = OrderedDict()
d['foo'] = 1
d['bar'] = 2
d['spam'] = 3
d['grok'] = 4
# Outputs "foo 1", "bar 2", "spam 3", "grok 4"
for key in d:
    print(key, d[key])

字典的運算

  • 對字典值執行計算操作,需要用zip()將鍵值反轉。
prices = {
    'ACME': 45.23,
    'AAPL': 612.78,
    'IBM': 205.55,
    'HPQ': 37.20,
    'FB': 10.75
}

min_price = min(zip(prices.values(), prices.keys()))
# min_price is (10.75, 'FB')
max_price = max(zip(prices.values(), prices.keys()))
# max_price is (612.78, 'AAPL')

prices_sorted = sorted(zip(prices.values(), prices.keys()))
# prices_sorted is [(10.75, 'FB'), (37.2, 'HPQ'),
#                   (45.23, 'ACME'), (205.55, 'IBM'),
#                   (612.78, 'AAPL')]

print(min_price,max_price,prices_sorted)

prices_and_names = zip(prices.values(), prices.keys())
print(min(prices_and_names)) # OK

查找兩個字典的交集

a = {
    'x' : 1,
    'y' : 2,
    'z' : 3
}

b = {
    'w' : 10,
    'x' : 11,
    'y' : 2
}

#鍵的交集
a.keys() & b.keys() # { 'x', 'y' }
#在
a.keys() - b.keys() # { 'z' }
# Find (key,value) pairs in common
a.items() & b.items() # { ('y', 2) }

減少硬編碼

a = slice(5, 50, 2)
a.start #5
a.stop #50
a.step #2
s = 'HelloWorld'
a.indices(len(s)) # (5, 50, 2)

統計序列中出現次數最多的元素

words = [
    'look', 'into', 'my', 'eyes', 'look', 'into', 'my', 'eyes',
    'the', 'eyes', 'the', 'eyes', 'the', 'eyes', 'not', 'around', 'the',
    'eyes', "don't", 'look', 'around', 'the', 'eyes', 'look', 'into',
    'my', 'eyes', "you're", 'under'
]
from collections import Counter
word_counts = Counter(words)
# 出現頻率最高的3個單詞
top_three = word_counts.most_common(3)
print(top_three)
# Outputs [('eyes', 8), ('the', 5), ('look', 4)]

通過某一關鍵字排序一個字典

  • 示例
rows = [
    {'fname': 'Brian', 'lname': 'Jones', 'uid': 1003},
    {'fname': 'David', 'lname': 'Beazley', 'uid': 1002},
    {'fname': 'John', 'lname': 'Cleese', 'uid': 1001},
    {'fname': 'Big', 'lname': 'Jones', 'uid': 1004}
]

from operator import itemgetter
rows_by_fname = sorted(rows, key=itemgetter('fname'))
rows_by_uid = sorted(rows, key=itemgetter('uid'))
print(rows_by_fname)
print(rows_by_uid)

通過某一字段將記錄分組

rows = [
    {'address': '5412 N CLARK', 'date': '07/01/2012'},
    {'address': '5148 N CLARK', 'date': '07/04/2012'},
    {'address': '5800 E 58TH', 'date': '07/02/2012'},
    {'address': '2122 N CLARK', 'date': '07/03/2012'},
    {'address': '5645 N RAVENSWOOD', 'date': '07/02/2012'},
    {'address': '1060 W ADDISON', 'date': '07/02/2012'},
    {'address': '4801 N BROADWAY', 'date': '07/01/2012'},
    {'address': '1039 W GRANVILLE', 'date': '07/04/2012'},
]


from operator import itemgetter
from itertools import groupby

# Sort by the desired field first
rows.sort(key=itemgetter('date'))
# Iterate in groups
for date, items in groupby(rows, key=itemgetter('date')):
    print(date)
    for i in items:
        print(' ', i)

字典篩選

  • p1 = dict((key, value) for key, value in prices.items() if value > 200)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章