1. 程式人生 > >python入門:基礎,列表、元組、字典及集合型別

python入門:基礎,列表、元組、字典及集合型別

這篇文章是python基本資料結構的高階教程,一般的用法請自行參考python入門教程

python入門教程

基礎

變數及其作用域

函式

運算子

Python運算子優先順序

從最高到最低優先順序的所有運算子

運算子描述
**指數 (最高優先順序)
~ + -按位翻轉, 一元加號和減號 (最後兩個的方法名為 [email protected][email protected])
* / % //乘,除,取模和取整除
+ -加法減法
>> <<右移,左移運算子
&位 'AND'
^ |位運算子
<= < > >=比較運算子
<> == !=等於運算子
= %= /= //= -= += *= **=賦值運算子
is is not身份運算子
in not in成員運算子
not or and邏輯運算子

Note: 位運算子優先順序相當低,所以位運算時記得加括號不出錯。

邏輯運算子

Python 中,and 和 or 執行布林邏輯演算,但是它們並不返回布林值,而是返回它們實際進行比較的值之一。

and 從左到右掃描,返回第一個為假的表示式值,無假值則返回最後一個表示式值。or 從左到右掃描,返回第一個為真的表示式值,無真值則返回最後一個表示式值。

>>> '' and 'b'
''
>>> 'a' and 'b' and 'c'
'c'
>>> '' or 'b'
'b'
>>> '' or [] or{}
{}

and-or搭配使用:

>>> a = "betabin"
>>> b = "python"
>>> 1 and a or b
'betabin'
>>> 0 and a or b
'python'
看起來類似於於我們C++中的條件運算子(bool?a:b),是的,當a為true的時候是一樣的。但是,當a為false的時候,就明顯不同了。如果堅持要用and-or技巧來實現條件運算子的話,可以用種安全的方法:
>>> a = ""
>>> b = "betabin"
>>> (1 and [a] or [b])[0]
''
就是萬能的[],把a為假的可能性給抹殺掉,然後通過[0]再獲得(因為要通過[0]獲得元素,所以b也得加上[])。這個and-or技巧主要在lambda中使用。

python除法

python2除法真是個大坑!

比較

python中運算子‘is’,'is not'和‘==’,’!=‘的區別
is,is not是地址比較
==,!= 是值比較

值和地址的比較

常量的地址是不變的:

k = -1

k == -1 True k is -1 True

列表就不是常量了
a = [123.4, 234.4]
b = [123.4, 234.4]
print(a == b)
True
print(a is b)
False

學習資源

python高階基礎:python語法糖

Python實現兩個變數值交換

a,b = b,a

if else表示式

fpython沒有三目運算子,我挺苦惱的,比如把兩個整數較大的那個複製給一個變數,有三目運算子的語言會這樣寫:
c = a > b ? a : b
後來發現Python的if語句可以寫成一行完成上述功能:
c = a if a > b else b

執行字串表示式eval

eval執行一個字串表示式,並返回表示式的值。
print eval("1 + 1")
>> 2
再來個複雜點的:
def init():
    return 1
def func(num):
    return 2
action = {"num": init, "func": func}
expression = 'func(num)'
print eval(expression, action)
>> 2

python for迴圈高階用法

for/else我們經常使用for迴圈來查詢元素,有兩個場景會使迴圈停下來:
元素被找到,觸發break。
迴圈結束。
但是我們並不知道是哪個原因導致迴圈結束,通常是設定一個標記,元素被找到,改變標記的值。for/else可以很優雅地解決這個問題:
for i in range(10):
if i > 10:
    print i
else:
    print("can't find result")

在分支語句中使用else子句在一些常見的程式語言中的用法基本相同,類似於提供了一條預設的執行路徑,配合if等條件判斷語句使用,相比其它的程式語言(c#, java, js等)在python中,else有一些特殊的用法,配合for, while等迴圈語句使用,甚至還能配合異常處理try except語句進行使用,能夠讓我們的程式碼更加的簡潔。

配合for/while迴圈語句使用
在for迴圈語句的後面緊接著else子句,在迴圈正常結束的時候(非return或者break等提前退出的情況下),else子句的邏輯就會被執行到。先來看一個例子:
def print_prime(n):
    for i in xrange(2, n):
        # found = True
        for j in xrange(2, i):
            if i % j == 0:
                 # found = False 
                break
        else:
            print "{} it's a prime number".format(i)
        # if found:
                  # print "{} it's a prime number".format(i)
print_prime(7)

2 it's a prime number
3 it's a prime number
5 it's a prime number
一個簡單列印素數的例子,判斷某個數字是否是素數的時候需要遍歷比它自己小的整數,任何一個滿足整除的情況則判斷結束,否則列印這是一個素數的info,有了else的加持,整個例子的邏輯相當的“self-expressive”,如同虛擬碼一般的好理解而且相比在判斷整除的時候設定標誌值然後在函式的結尾處判斷標誌值決定是否列印數字時素數的訊息,程式碼更簡潔沒有那麼多要描述如何做的“過程式”準備工作。
大家可以把例子中的被註釋程式碼執行對比下效果。

python跳出多層迴圈

1、自定義異常
class getoutofloop(Exception): pass
try:
    for i in range(5):
        for j in range(5):
            for k in range(5):
                if i == j == k == 3:
                    raise getoutofloop()
                else:
                    print i, '----', j, '----', k
except getoutofloop:
    pass
2、封裝為函式return
def test():
    for i in range(5):
        for j in range(5):
            for k in range(5):
                if i == j == k == 3:
                    return
                else:
                    print i, '----', j, '----', k
test()
3、for … else … 用法
上面的兩種都是隻能跳出多層而不能跳出特定層數的迴圈,接下來的這個正是為了跳出特定層數的迴圈。
for i in range(5):
    for j in range(5):
        for k in range(5):
            if i == j == k == 3:
                break
            else:
                print i, '----', j, '----', k
        else: continue
        break
    else: continue
    break
else在 while和for 正常迴圈完成之後執行,和直接寫在 while和for 之後沒有區別,但是如果用break結束迴圈之後else就不會執行了。

不過要是有多次跳出不同層的迴圈的需求,也沒轍了。

序列迭代

複雜迭代例項

test_dict = {(1, 2): [3, 4, 5]}
for e, (w, *f) in test_dict.items():
print(e, w, f)
for e, w, *f in test_dict.items():
print(e, w, f)
(1, 2) 3 [4, 5]
(1, 2) [3, 4, 5] []

反向迭代

對於普通的序列(列表),我們可以通過內建的reversed()函式進行反向迭代:
# 通過 reversed 進行反向迭代
for i in reversed(list_example):
    print(i)
# 但無法作用於 集合 和 迭代器
除此以外,還可以通過實現類裡的__reversed__方法,將類進行反向迭代:
class Countdown:
    def __init__(self, start):
        self.start = start

    # 正向迭代
    def __iter__(self):
        n = self.start
        while n > 0:
            yield n
            n -= 1

    # 反向迭代
    def __reversed__(self):
        n = 1
        while n <= self.start:
            yield n
            n += 1

python列表list

在Python中,列表是一個動態的指標陣列。[

函式的預設引數一定不要設定為可變型別如list,否則會出現潛在的錯誤

python列表的建立、插入、丟擲、拆箱操作

建立

通過字串建立

s = 'asdf

list(s)

['a', 's', 'd', 'f']

還有其它資料型別如tuple的轉換等等

list的插入操作是呼叫函式listinsert來實現的。

該函式的流程如下:

1、解析引數。

2、呼叫靜態函式ins1進行插入操作。

list的插入操作對索引值的處理在函式ins1中進行,相關處理過程如下:

1、將列表的條目數賦值給n;
2、如果索引值小於0,則將索引值增加n;如果仍小於0,則將索引值賦值為0;
3、如果索引值大於n,則將索引值賦值為n。

list中新增元素append

list.append()返回None

如果程式碼全寫在同一行如列表解析中,不想返回None而是返回新增後的列表,可以使用list + [元素]也就是list+list。

丟擲操作當條目索引為負數時的處理

list的丟擲操作是將指定索引位置的條目從列表中刪除並且返回該條目的值。list的丟擲操作是呼叫函式listpop來實現的。

對索引值index的相關處理過程如下:

1、如果index小於0,則將index增加列表本身的條目數;

2、如果index仍小於0或大於列表條目數,則輸出錯誤資訊提示索引值超出範圍。

原始碼中將操作位置初始化為-1,所以如果沒有指定丟擲位置,則預設丟擲最後一個條目。

拆箱

>>> a, b, c = [1,2,3]>>> a, b, c(1,2,3)>>> a, b, c = (2*i+1foriinrange(3))>>> a, b, c(1,3,5)>>> a, (b, c), d=[1, (2,3),4]>>> a1>>> b2>>> c3>>> d4

擴充套件的拆箱(Python 3支援)

>>> a, *b, c=[1,2,3,4,5]>>> a1>>> b[2,3,4]>>> c5

python列表查詢、索引和統計

List slices with step (a[start:end:step])帶步長列表切片

1 如果從列表開頭開始切割,那麼忽略 start 位的 0,例如list[:4];如果一直切到列表尾部,則忽略 end 位的 0,例如list[3:]。
2 切割列表時,即便 start 或者 end 索引跨界也不會有問題。正如人們所期望的,試圖訪問一個超過列表索引值的成員將導致 IndexError(比如訪問以上列表的 list[10])。儘管如此,試圖訪問一個列表的以超出列表成員數作為開始索引的切片將不會導致 IndexError,並且將僅僅返回一個空列表。
3 列表切片不會改變原列表(都是淺拷貝。索引都留空時,會生成一份原列表的淺拷貝。b = a[:]   assert b == a and b is not a # true。注意這個屬性和numpy不一樣,numpy中切片是多維陣列物件的檢視!

Note: b = a直接賦值的話,兩個列表就是同一個列表,相當於檢視,沒有任何copy。[python模組 - copy模組]

>>> a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> a[::2]
[0, 2, 4, 6, 8, 10]

list = ['a', 'b', 'c', 'd', 'e']
print list[10:]
以上程式碼將輸出 [],並且不會導致一個 IndexError。

List slice assignment列表切片賦值

>>> a = [1, 2, 3, 4, 5]
>>> a[2:3] = [0, 0]
>>> a
[1, 2, 0, 0, 4, 5]
>>> a[1:1] = [8, 9]
>>> a
[1, 8, 9, 2, 0, 0, 4, 5]
>>> a[1:-1] = []
>>> a
[1, 5]

python列表取倒數n個數

a = [1,2,3,4,5,6]
print(a[-3:])

python列表反轉

a = a[::-1]

切片命名(slice(start, end, step))

>>> a =[0,1,2,3,4,5]>>> LASTTHREE = slice(-3,None)>>> LASTTHREEslice(-3,None,None)>>> a[LASTTHREE][3,4,5]

python列表查詢某個元素

1.

try:
k = l.index(4)    #index查詢不存在的元素會出異常
except:
k = 3

比2好,不用搜索列表兩次,更快。

2.

if 4 not in l:
k = 3
else:
k = l.index(4)

3. 如果列表元素很多(如大於10000),應先轉換成字典再查詢(更耗用記憶體),速度不只100倍的提升!

fs_dict = dict.fromkeys(fs_list, True)
[(u, v) for u, v in fs_dict]

最大和最小元素(heapq.nlargest andheapq.nsmallest)

>>> a = [random.randint(0, 100) for __ in range(100)]
>>> heapq.nsmallest(5, a)
[3, 3, 5, 6, 8]
>>> heapq.nlargest(5, a)
[100, 100, 99, 98, 98]

python列表統計

統計某個元素個數count()

list支援count方法

>>> a = ['a', 'b', 'c', 3, '4', '2', '2', 2, 2]
>>> a.count(2)
2
>>> a.count('a')
1
>>> a.count('d')
0

[True,True,False].count(True)
2

當然統計True,False這種可以使用sum方法

>>> l = [1, 2, True, False]
>>> sum(bool(x) for x in l)
3

統計列表中所有元素出現次數

使用pandas頂級函式pd.value_counts,value_counts是一個頂級pandas方法,可用於任何陣列或序列:

>>> pd.value_counts(obj.values, sort=False)

比列表解析要快2倍以上(時間包含了列表轉換成ndarray的時間,如果已經是ndarray要快10倍左右)。

paths_len_dict_list = {len: values.count(len) for len in set(values)}

python列表刪除操作

python列表中刪除某個元素

使用del關鍵字刪除指定位置的元素
input = [1,2,3,4]
del input[1]
使用pop方法刪除指定位置的元素
input = [1,2,4,5,6]
input.pop(2)
注意list的pop方法如果指定引數的話,會刪除指定索引位置的元素,如果未指定將刪除list的最後一個元素。

python列表中刪除某個元素所有的出現,如空字串

while '' in classified_sentences:
classified_sentences.remove('')

python清空列表的幾種方式

1. s.clear() 

2. del s[:] 

3. s[:] = [] 

4. s *= 0

python列表、元組排序

list.sort()一般用法:指定軸axis;自定義comparator函式key; 升降序選擇reverse。

list.sort(axis = None, key=lambda x:x[1], reverse = True)

python列表拷貝

python中怎麼對一個列表賦值並修改不影響原來的列表?

  1. 簡單列表的拷貝

    已知一個列表,求生成一個新的列表,列表元素是原列表的複製

    a=[1,2]
    b=a

    這種其實並未真正生成一個新的列表,b指向的仍然是a所指向的物件。

    後果:如果對a或b的元素進行修改,a,b的值同時發生變化:a.remove(1)則對應b也變為[2]

  2. 可以使用以下方法解決

    a=[1,2]
    b=a[:]

    這樣修改a對b沒有影響。修改b對a沒有影響。

  3. 列表拷貝

             a = [1,2,3]

             b = a.copy()

             print(id(a), id(b))

        4.複雜列表的拷貝

              可以使用copy模組中的deepcopy函式。修改測試如下:

              import copy
              a=[1,[2]]

              b=copy.deepcopy(a)

python兩個列表的操作

python兩個列表相減

方法1. 用set(集合)操作
list3 = list(set(list1) - set(list2))
set操作會將一個list轉換成一個集合,重複的項會被刪除。
方法2.列表解析list3 = [i for i in list1 if i not in list2]
但是在list很大的時候,沒有set方法快。

python中求兩個list的交集,兩個list是否有交集

list1 = [1,2]
list2 = [2,3]
print(set(list1).intersection(set(list2)))
{2}

python兩個列表合併extend

list.extend(seq)
Note:在列表末尾一次性追加另一個序列中的多個值(用新列表擴充套件原來的列表)

返回none

如果不想改變原來list,可以用new_list = copy.deepcopy(list)

Flattening lists扁平列表

python的for迴圈從兩個不同列表中同時取出兩個元素zip

zip(): 如果你多個等長的序列,然後想要每次迴圈時從各個序列分別取出一個元素,可以利用zip()方便地實現:

ta = [1,2,3]
tb = [9,8,7]
tc = ['a','b','c']
for (a,b,c) in zip(ta,tb,tc):
    print(a,b,c)

一個for迴圈中每次迭代輸出兩個列表對應的元素及對應的索引號enumerate&zip

users = [1,2,3]
items = [4,5,6]
for index, (user, item) in enumerate(zip(users, items)):
print(index, user, item)
0 1 4
1 2 5
2 3 6

python列表其它操作

在python列表中每個元素間新增逗號,

(最後一個元素後面不加,,這裡a中的元素必須是字串)

a = ['12', '34', '45']
s = ','.join(a)
print(s)
12,34,45

當然如果x中的元素不是字串可以先轉換一下

[''.join(xi) for xi in np.array(x).astype(str)]

列表解析和條件表示式

列表解析( List comprehensions)

列表解析一般都是下面的形式

[expr foriter_var initerable ifcond_expr]

迭代iterable裡所有內容,每一次迭代後,把iterable裡滿足cond_expr條件的內容放到iter_var中,再在表示式expr中應該iter_var的內容,最後用表示式的計算值生成一個列表。

Note: iterable不能是None型別,否則會報錯:notype is not iterable

# times even numbers by 2 and odd numbers by 3 mul = [num * 3 if num % 2 else num * 2 for num in numbers]

如果沒有else語句,只能將if語句放到後面

jiebaWords = [i for i in jiebaWords if len(i) >= 2]

雖然列表解析比for迴圈快很多,但是其實也沒那麼快,如

c = (np.array(a) ** 2).sum()
b = sum([i ** 2 for i in a])

numpy的計算比列表解析快4倍,甚至c = np.sum(np.array(a)); b = sum(a);都比列表的直接計算sum快一丟丟。

Note: 資料多時,列表推導式可能會消耗大量記憶體,此時建議使用生成器表示式。

列表解析的順序

[[i+j for i in 'abc'] for j in "def"]

先算內部的,結果為:[['a'+j,'b'+j,'c'+j] for j in "def"]
再算外部的,結果為:[['a'+'d','b'+'d','c'+'d'],['a'+'e','b'+'e','c'+'e'],['a'+'f','b'+'f','c'+'f']]
所以輸出為:[[‘ad’, ‘bd’, ‘cd’], [‘ae’, ‘be’, ‘ce’], [‘af’, ‘bf’, ‘cf’]]

列表解析加速

列表解析中呼叫函式

lz提示,千萬不要在列表解析中使用計算時間長的函式或者什麼的,這樣每次for解析時都會重新呼叫一次那個函式。所以不要過於依賴列表解析的程式碼簡潔性。

It is very complex for the compiler/interpreter to determine that the function need not to be called many times. It is then very probable that the function is called many times.

列表解析的其它可參考優化

使用列表解析時,if語句中有in list語句時

python列表和json格式的相互轉換

list實現棧

use a list as a stack: #像棧一樣使用列表
stack = [3, 4, 5]
stack.append(6)
stack.append(7)
stack
[3, 4, 5, 6, 7]
stack.pop() #刪除最後一個物件
7
stack
[3, 4, 5, 6]
stack.pop()
6
stack.pop()
5
stack
[3, 4]

佇列實現

use a list as a queue: #像佇列一樣使用列表
> from collections import deque #這裡需要使用模組deque
> queue = deque(["Eric", "John", "Michael"])
> queue.append("Terry")           # Terry arrives
> queue.append("Graham")          # Graham arrives
> queue.popleft()                 # The first to arrive now leaves
'Eric'
> queue.popleft()                 # The second to arrive now leaves
'John'
> queue                           # Remaining queue in order of arrival
deque(['Michael', 'Terry', 'Graham'])

python元組操作

1個元素的tuple

元組中只包含一個元素時,需要在元素後面新增逗號來消除歧義tup1 = (50,)

要定義一個只有1個元素的tuple,如果你這麼定義:
>>> t = (1)
>>> t
1
定義的不是tuple,是1這個數!這是因為括號()既可以表示tuple,又可以表示數學公式中的小括號,這就產生了歧義,因此,Python規定,這種情況下,按小括號進行計算,計算結果自然是1。

元組連線組合

元組中的元素值是不允許修改的,但我們可以對元組進行連線組合,如下例項:
tup1 = (12, 34.56);
tup2 = ('abc', 'xyz');
# 以下修改元組元素操作是非法的。
# tup1[0] = 100;
# 建立一個新的元組
tup3 = tup1 + tup2;
print tup3;
#(12, 34.56, 'abc', 'xyz')

一個“可變的”tuple

t = ('a', 'b', ['A', 'B'])
t[2].append(1)
t[2][1] = 2
print(t)
('a', 'b', ['A', 2, 1])

當然tuple中如果存在可變的元素後就不能使用dict型別的key了。

命名元組namedtuple

因為 tuple 作為沒有名字的記錄來使用在某些場景有一定的侷限性,所以又有了一個 namedtuple 型別的存在,namedtuple 可以指定欄位名,用來當做一種輕量級的類來使用。

python列表和元組的區別和聯絡

相同點:

列表與元組都是序列型別,都是序列型別的容器物件,可以存放任何型別的資料、支援切片、迭代等操作。二者都可以包含任意型別的元素甚至可以是一個序列,還可以包含元素的順序(不像集合和字典)。

異點:

兩種型別除了字面上的區別(括號與方括號)之外,最重要的一點是tuple是不可變型別,大小固定,而 list 是可變型別、資料可以動態變化,這種差異使得兩者提供的方法、應用場景、效能上都有很大的區別。

1 列表特有方法所有的操作都基於原來列表進行更新,而 tuple 作為一種不可變的資料型別,同樣大小的資料,初始化和迭代 tuple 都要快於 list。同樣大小的資料,tuple 佔用的記憶體空間更少。

2 原子性的 tuple 物件還可作為字典的鍵。(例如上面的一個“可變的”tuple就不是原子性的,不能作為字典的鍵)。

3 同構 VS 異構

tuple 用於儲存異構(heterogeneous)資料,當做沒有欄位名的記錄來用,比如用 tuple 來記錄一個人的身高、體重、年齡。person = ("zhangsan", 20, 180, 80)

而列表一般用於儲存同構資料(homogenous),同構資料就是具有相同意義的資料,比如下面的都是字串型別["zhangsan", "Lisi", "wangwu"]

再比如 list 存放的多條使用者記錄[("zhangsan", 20, 180, 80), ("wangwu", 20, 180, 80)]。資料庫操作中查詢出來的記錄就是由元組構成的列表結構。

4 列表和元組的“技術差異”是,列表是可變的,而元組是不可變的。這是在 Python 語言中二者唯一的差別。比如:列表有一個 append() 的方法來新增更多的元素,而元組卻沒有這個方法。元組並不需要一個 append() 方法,因為元組不能修改。比如你不能把列表當做字典的關鍵字,因為只有不可變的值才能進行雜湊運算,因此只有不可變的值才能作為關鍵字。要使用列表做關鍵字,你需要把它轉化為元組。

5 “文化差異“是指二者在實際使用中的差異:在你有一些不確定長度的相同型別佇列的時候使用列表;在你提前知道元素數量的情況下使用元組,因為元素的位置很重要。

舉個例子,假設你有一個函式是用來在目錄中查詢結尾為 *.py 的檔案。函式返回的應該是一個列表,因為你並不知道你會找到多少個檔案,而這些檔案都有相同的含義:它們僅僅是你找到的另一個檔案。另一方面,讓我們假設你需要儲存五個值來代表氣象觀測站的位置:id ,城市,國家,緯度,經度。元組就比列表更適用於這種情況。

把這種“文化差異”放到 C 語言來講,列表像是陣列,元組則像是 structs 結構體

{lz:python函式引數如果傳遞的是元組,則為值傳遞;如果傳遞的是列表,則為地址傳遞。這個同c++一樣!}[]

在引數陣列中,位置很重要,因為他們是位置引數。但是在函式中,它會接收引數陣列並傳入另一個函式,它僅僅是一組引數,與其他引數並無不同。其中一些會在呼叫中變化。Python 之所以在這裡使用元組是因為元組比列表更節省空間。列表被重複分配使得在新增元素上更快。這體現了 Python 的實用性:相比於在引數陣列上,列表/元組的語義差別,在這種情況下,使用這種資料結構更好。

大部分情況下,你應該根據文化差異來選擇使用列表還是元組。思考下你資料的含義。如果實際上根據你的程式來計算,你的資料長度並不固定,那麼可能用列表更好。如果在寫程式碼時你知道第三個元素的含義,那麼用元組更好。另一方面,函數語言程式設計強調使用不可變的資料結構來避免產生使程式碼變得更難解讀的副作用。如果你喜歡使用函數語言程式設計,那麼你可能因為元組的不可變而更喜歡它們。


python字典dict

字典除了一般的對映使用,還可以從用於稀疏資料結構角度看:
例如多維陣列中只有少數位置上有儲存的值
>>> M={}
>>> M[(2,3,4)]=88
>>> M[(7,8,9)]=99  
{(2, 3, 4): 88, (7, 8, 9): 99}
鍵是元組,他們記錄非空元素的座標。我們並不是分配一個龐大而幾乎為空的三維矩陣,而是使用一個簡單的兩個元素的字典。通過這一方式讀取空元素的時,會觸發鍵不存在的異常。因為這些元素實質上並沒有被儲存。

python字典構建和初始化

鍵和值的限制

Python呼叫內部的雜湊函式,將鍵作為引數進行轉換,得到一個唯一的地址(這也就解釋了為什麼給相同的鍵賦值會直接覆蓋的原因,因為相同的鍵轉換後的地址是一樣滴),然後將值存放到該地址中。

1)不允許同一個鍵出現兩次。建立時如果同一個鍵被賦值兩次,後一個值會被記住。雜湊演算法對相同的值計算結果一樣,也就是說1和1.0經過雜湊函式得到相同的地址,也就認為這兩個鍵相同。即1和1.0也是相同的鍵!

2)字典值可以沒有限制地取任何python物件,既可以是標準的物件,也可以是使用者定義的。

另外,key是不能修改的,主要是內部結構是有序的,改了就破壞了樹結構。所以如果想要修改key,就要先刪除再插入。(或者直接過載一下dict的賦值運算?)

zip構建

dict(zip(names, range(len(names)))) 

列表轉換成字典

fs_dict = dict.fromkeys(fs_list, True)

Note: dict.fromkeys函式返回的是一個新的dict,而不是改變原dict。所以dict1.fromkeys((1, 2, 3), 'new')是沒有效果的。

元組列表轉換成字典

dict(seq):建立一個字典,seq必須是一個序列(key,value)元組。

>>> list1 = [(1,2),(2,3)]

>>> dict(list1)

{1: 2, 2: 3}

python dict字典的key必須是hashable的:key不能是list, set(否則出錯TypeError: unhashable type: 'list'), 但可以是tuple

{(1, 2): '5', (3, 2): '5'}

python dict字典的key應該會自動轉換成同一型別(所有key型別的最小型別?),所以前面的1會被後面的1.0覆蓋,而後面的浮點型別1.0會自動轉換成int型別1。

In[4]: d = {1:2, 1.0:3}
In[5]: d[1]
3
In[6]: len(d)
1
In[7]: d.keys()
dict_keys([1])

d = {1.0:3}
In[9]: d.keys()
dict_keys([1.0])

python字典初始化

python字典設定value初始型別,指定字典的value型別。

dict字典元素型別初始化設定

music_tag = dict()
for music_name in music_names:
music_tag.setdefault(music_name, [])
    for filename in filenames:
if music_name in [line.strip() for line in open(join(DIR, filename))]:
music_tag[music_name] += filename.split('.')[0]
dict.setdefault(key, default=None) get()類似, 但如果鍵不存在於字典中,將會新增鍵並將值設為default
defaultdict的程式碼效率高於下面的等效程式碼:
>>> d = {}
>>> for k, v in s:
...     d.setdefault(k, []).append(v)

defaultdict字典初始化

python dict字典for迴圈輸出

dict1 = {1: 1, 2: 1, 3: 1}
for i in dict1: #等價於dic1.keys()

字典中新增和刪除元素

dict.add()返回None

dict刪除元素或者整個字典

del dict2['name'] # 刪除鍵為“name”的條目

dict2.clear() # 刪除dict2 中所有的條目

del dict2 # 刪除整個dict2 字典

dict2.pop('name') # 刪除並返回鍵為“name”的條目

字典解構**

params = {'n_estimators': 500, 'max_depth': 4, 'min_samples_split': 2, 'learning_rate': 0.01, 'loss': 'ls'}
clf = ensemble.GradientBoostingRegressor(**params)

python 字典查詢

1. 通過value 找出key

任何時刻dict.keys()和dict.values()的順序都是對應的。
try:
    return dict.keys()[dict.values().index(value)]         #python3中要修改為list(dict.keys())[list(dict.values()).index(value)]
except ValueError:
    pass

Note:往dict中新增元素,keys和values加入後都是無序的!但是加入之後相對位置不變。

2. 從字典中獲取元素

data = {'user': 1, 'name': 'Max', 'three': 4}

方法1:dict.get(key, default=None)

返回指定鍵的值,如果值不在字典中返回default值

is_admin = data.get('admin', False)

方法2:

try:

     is_admin = data['admin']

except KeyError:

     is_admin = False

python中兩個字典的操作

python兩個字典合併操作

dict1 = {1:1, 2:1, 3:1}
dict2 = {3:2, 4:2, 5:2}
dict1.update(dict2)
print(dict1)

Note: dict key相同的value以更新值為主,也就是dict2。

Adding two dictionaries兩個字典相加(合併)

x = {'a':1, 'b': 2}y = {'b':10, 'c': 11, 'a':3, 'd':7}
方式1

for k, v in y.items():
if k in x:
x[k] += v
    else:
x[k] = v
方式2
from collections import Counter

z = Counter(x) + Counter(y)
方式3
z = {a: x.get(a, 0) + y.get(a, 0) for a in set(x) | set(y)}
print z>>>{'a': 4, 'c': 11, 'b': 12, 'd': 7}
Note: 方式1最快,其次方式3。所以簡單的程式還是自己手寫比較好。

兩個字典相減

pos = dict.fromkeys(random.randint(0, 1000000, size=1000000), True)
gt1 = dict.fromkeys(random.randint(0, 1000000, size=1000000), True)
方式1
r = {k: v for k, v in pos.items() if k not in gt1}
方式2
from collections import Counter
r = Counter(pos) - Counter(gt1)
Note: 方式1更快。

python字典排序

對字典按鍵/按值排序,用元組列表的形式返回,同時使用lambda函式來進行;

sorted(iterable[, cmp[, key[, reverse]]]
cmp和key一般使用lambda

對字典按鍵key排序,用元組列表的形式返回

1. 使用lambda函式

d = {3:5, 6:3, 2:4}
ds = sorted(d.items(), key=lambda item:item[0], reverse=True) #d[0]表示字典的鍵
print(ds)
[(6, 3), (3, 5), (2, 4)]

2.採用operator模組的itemgetter函式

from operator import itemgetter
sorted(d, key=itemgetter(1))

對字典按值value排序,用元組列表的形式返回

ds = sorted(ds.items(), key=lambda item:item[1], reverse=True)
print(ds)
[(3, 5), (2, 4), (6, 3)]
print(dict(ds))    #又變成無序的了
{2: 4, 3: 5, 6: 3}

分解程式碼:d.items() 得到[(鍵,值)]的列表。然後用sorted方法,通過key這個引數,指定排序是按照value,也就是第一個元素d[1]的值來排序。reverse = True表示是需要翻轉的,預設是從小到大,翻轉的話,那就是從大到小。

collections.OrderedDict有序字典

Dictionary Comprehensions字典解析

One use for generators can be to build a dictionary, like in the first example below. This proved itself to be common enough that now there is even a newdictionary comprehension syntax for it. Both of these examples swap the keys and values of the dictionary.

teachers = { 'Andy': 'English', 'Joan': 'Maths', 'Alice': 'Computer Science', } # using a list comprehension subjects = dict((subject, teacher) for teacher, subject in teachers.items()) # using a dictionary comprehension subjects = {subject: teacher for teacher, subject in teachers.items()}

>>> m = {x: 'A' + str(x) for x in range(10)}

{0: 'A0', 1: 'A1', 2: 'A2', 3: 'A3', 4: 'A4', 5: 'A5', 6: 'A6', 7: 'A7', 8: 'A8', 9: 'A9'}

Note: 字典解析中的if判斷是對value來說的,如:

loc2type_dict = {vid: vcat.split(',') if not pd.isnull(vcat) else ['notype'] for _, (vid, vcat) in df.iterrows()}

Inverting a dictionary using a dictionary comprehension翻轉字典中的key和value

>>> m = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
>>> m
{'d': 4, 'a': 1, 'b': 2, 'c': 3}
>>> {v: k for k, v in m.items()}
{1: 'a', 2: 'b', 3: 'c', 4: 'd'}

Note: 也可以使用zip反相字典物件

python dict和set都是使用hash表來實現(類似C++11標準庫中unordered_map),查詢元素的時間複雜度是O(1)。dict和set的查詢效能差不多(如在list中in查詢時)。

python集合操作

集合是無序的!

集合加入、刪除元素

add(elem)(已存在就不加入)

Add element elem to the set.

remove(elem)

Remove element elem from the set. Raises KeyError if elem isnot contained in the set.

discard(elem)

Remove element elem from the set if it is present.

pop()

Remove and return an arbitrary element from the set. RaisesKeyError if the set is empty.

clear()

Remove all elements from the set.

將整個新集合加入到本集合中

update(*others)

集合間操作

>>> a = set('abracadabra')

>>> b = set('alacazam')
>>> a                                  # unique letters in a
set(['a', 'r', 'b', 'c', 'd'])
>>> a - b                              # letters in a but not in b
set(['r', 'd', 'b'])
>>> a | b                              # letters in either a or b
set(['a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'])
>>> a & b                              # letters in both a and b
set(['a', 'c'])
>>> a ^ b                              # letters in a or b but not both

set(['r', 'd', 'b', 'm', 'z', 'l'])

判斷子集、父集

issuperset(other)

s = {1, 2, 3, 4}
a = (1, 2)
if s.issuperset([*a]):
print('***')

issubset(other)

相關推薦

python入門基礎列表字典集合型別

這篇文章是python基本資料結構的高階教程,一般的用法請自行參考python入門教程python入門教程基礎變數及其作用域函式運算子Python運算子優先順序從最高到最低優先順序的所有運算子運算子描述**指數 (最高優先順序)~ + -按位翻轉, 一元加號和減號 (最後兩個

Python自學入門學習基礎之一: 列表

Python自學 Python列表和元祖 Python基礎學習 本人從事Python多年,有好多小夥伴加了我之後說:有沒有相對來說簡單點的教程,你寫的一些大項目我們小編看不懂!!今天我就發一篇小白入門學習之一的基礎,列表和元祖,歡迎大家訂閱公眾號:Python從程序猿到程序猿,或者加 ,山君:49

PYTHON 列表&&字典&集合

列表(list) 有序性,可儲存任意型別的值 通過偏移存取,支援索引來讀取元素,第一個索引為0 ,倒數第一個索引為-1 可變性 ,支援切片、合併、刪除等操作 可通過索引來向指定位置插入元素 可通過pop()方法刪除末尾元素,pop(索引位置)來刪除指定位置元素

Python基礎知識】基本數據類型數字字符串列表字典集合

tuple 位置 環境 htm 邏輯 python3 修改 yield 啟動 1.查看Python版本 python -V 2.Windows系統下使用命令行設置環境變量:path=%path%;D:\Python 3.幾個重要的Python環境變量 PYTHONPA

Python基礎列表字典

Python中最為常用的資料容器有列表、元組和字典。是使用Python必須掌握的基礎。本文詳細介紹列表、元組和字典,以及字典的兩種(按照key排序和按照value排序)排序方法。 一、列表 1.建立 list1 = [1,2,3,4,5,6] list2 = ['a','b','c','

python基礎《四列表字典

''' 字典用法擴充套件: 用字典對映簡單的switch case 語句 其他語言中有switch case用法,但是python中沒有,不過可以用字典對映來代替 如下: ------------------虛擬碼分割線------------------ # 功能:實現輸入數字0-7,打印出相應的英文星期幾

python基礎(5)---整型字符串列表字典內置方法和文件操作介紹

進制 res cde __init__ little 計算 技術分享 圖片 pos   對於python而言,一切事物都是對象,對象是基於類創建的,對象繼承了類的屬性,方法等特性     1.int   首先,我們來查看下int包含了哪些函數 # python3.x di

PYTHON開發基礎04-列表字典操作練習

現在 aac 內容 pan 字典 方案 alt play span 練習1: # l1 = [11,22,33]# l2 = [22,33,44]# a. 獲取內容相同的元素列表# b. 獲取 l1 中有, l2 中沒有的元素列表# c.

python全棧學習總結二數字字符串列表字典重要特點方法

info ted 填充 tde 拼接字符串 enc 支持中文 display sort 一 python中數據類型   整形:int   字符串:str   列表:list   元組:tuple   字典:dict   布爾值:bool   浮點型:float   一切皆對

Python學習之路——Python基礎之基本資料型別(列表字典)

基本資料型別 數字 字串 列表 list 元組 tuple 字典 dict 布林值 bool 列表和元組 列表:有序,元素可以被修改元組: 書寫格式:元組的一級元素不可被修改,不能被增加或者刪除,一般寫元租的時候,推薦在最後加入',' 索引:v =

Python學習之路——Python基礎之基本數據類型(列表字典)

bre mark 有序 數據 str sca 索引 更新 蘋果 基本數據類型 數字 字符串 列表 list 元組 tuple 字典 dict 布爾值 bool 列表和元組 列表:有序,元素可以被修改元組: 書寫格式:元組的一級元素不可被修改,不能被增加或者刪除,一般寫

Python基礎(模塊初識字符串列表字典的用法)

tde sort 開始 添加 isalnum 衢州 pca ascii碼表 單個 模塊(Module)初識 python模塊是一個python文件,以.py結尾。模塊中定義了一些變量及函數,可以在需要的時候引用模塊,調用其中的變量及函數。可以調用系統模塊或導入第三方模塊調用

python基礎-字串列表字典

c語言中,     儲存多個數據的方式     陣列,,,int age[10]     while     do-while     for                  for(int i=0; i<5; i++){             迴圈條件滿足

Python容器列表字典集合

文章目錄 序言 序列 字串(string) 建立字串 字串的簡單操作 相關操作函式 列表(list) 建立列表 列表的簡單操作 列表函式

Python基礎筆記_Day05_列表字典集合生成器迭代器

Day05_列表、元組、字典、集合、生成器、迭代器   05.01_Python語言基礎(列表List)(掌握) 05.02_Python語言基礎(建立列表)(掌握) 05.03_Python語言基礎(執行輸出列表)(掌握) 05.04_Python語言基礎(列表常用操

Python基礎-列表字典

#!/usr/bin/env python# -*- coding:utf-8 -*- # v = "李傑"# for item in v:# print(item)#######################################################################

python序列的三種類型列表字典

python的資料結構主要就是序列,而列表、元組和字典三種類型比較容易混淆,特地做了個筆記記錄了一下,供大家學習:原文地址:http://www.rednat.com/archives/python-sequence-of-three-types-lists-tuples-dictionaries.htm

Python入門筆記2 序列(字串列表

操作字串的方法: a.索引取值   a='abcde'   a[0]、a[1]取a中元素,但一次只可以取一個。   用+號連線,如,a[1]+a[2]。得‘ab’ b.切片 可以從字串中進行擷取 分正負數,正數表示從左往右取,從0開始;負數代表從右往左取,最後一位為-1

一句python一句R︱列表字典資料型別自定義模組匯入(格式去重)

先學了R,最近剛剛上手python,所以想著將python和R結合起來互相對比來更好理解python。最好就是一句python,對應寫一句R。pandas中有類似R中的read.table的功能,而且很像。———————————————————————————————————

Python列表字典集合與字串相關函式持續更新中……

> 本篇部落格為博主第一次學 Python 所做的筆記(希望讀者能夠少點浮躁,認真閱讀,平心靜氣學習!) **補充:** - 列表、元組和字串共同屬性: - 屬於有序序列,其中的元素有嚴格的先後順序 - 都支援雙向索引,索引範圍 [ -L, L-1 ] ,L -- 表示列表、元組和字串的長度(分正向索引