玩轉python字典與列表(上)

dwzb發表於2018-05-26

本文首發於知乎

我們來看下面6組資料

d = {'name' : ['a', 'b', 'c'],
    'num' : [1, 2, 3]}
lt = [('a', 1), ('b', 2), ('c', 3)]
ld = [{'name': 'a', 'num': 1}, 
      {'name': 'b', 'num': 2},
      {'name': 'c', 'num': 3}]

ld1 = [{'a': 1}, {'b': 2}, {'c': 3}]
ls = [{'a', 1}, {'b', 2}, {'c', 3}]
d1 = {'a': 1, 'b': 2, 'c': 3}
複製程式碼

考慮一下他們都表示什麼,他們之間的關係是什麼,有沒有發矇?

下面我們就好好理一下這些基礎的資料型別

1.從data.frame的角度考慮

從data.frame的角度考慮,前面三個的內在含義是一樣的,它們都可以直接呼叫pandas庫中的DataFrame函式構造一個資料框,如下所示

>>> d = {'name' : ['a', 'b', 'c'],
...     'num' : [1, 2, 3]}
>>> lt = [('a', 1), ('b', 2), ('c', 3)]
>>> ld = [{'name': 'a', 'num': 1},
...       {'name': 'b', 'num': 2},
...       {'name': 'c', 'num': 3}]
>>>
>>> import pandas as pd
>>> pd.DataFrame(d)
  name  num
0    a    1
1    b    2
2    c    3
>>> pd.DataFrame(lt, columns=('name', 'num'))
  name  num
0    a    1
1    b    2
2    c    3
>>> pd.DataFrame(ld)
  name  num
0    a    1
1    b    2
2    c    3
複製程式碼

d是按照列拆分,lt是按照行拆分,ld也是按行拆分,只是每次都帶有索引項。

我們用爬蟲抓取到的資料最常見的是ld的形式,如下圖所示

(改進 json)

ld向其他兩種型別轉化的程式碼如下所示

>>> ld
[{'name': 'a', 'num': 1}, {'name': 'b', 'num': 2}, {'name': 'c', 'num': 3}]
>>> [tuple(i.values()) for i in ld]
[('a', 1), ('b', 2), ('c', 3)]
>>> {'name': [d['name'] for d in ld],
...  'num': [d['num'] for d in ld]}
{'name': ['a', 'b', 'c'], 'num': [1, 2, 3]}
複製程式碼

兩兩相互轉化也是可以實現的,思路類似,這裡不再贅述

2.字典融合

來看下面這兩個之間的關係

ld1 = [{'a': 1}, {'b': 2}, {'c': 3}]
d1 = {'a': 1, 'b': 2, 'c': 3}
複製程式碼

一個字典內本身就可以有多個鍵值對,所以說以字典為元素的列表,是可以融合成為一個字典的

>>> ld1 = [{'a': 1}, {'b': 2}, {'c': 3}]
>>> result = {}
>>> for d in ld1:
...     result.update(d)
...
>>> result
{'c': 3, 'a': 1, 'b': 2}

# 第二種方法
>>> {k:v for d in ld1 for k,v in d.items()}
{'c': 3, 'a': 1, 'b': 2}
複製程式碼

一個字典當然也可以拆分成多個小字典的列表

>>> d1 = {'a': 1, 'b': 2, 'c': 3}
>>> [{k:v} for k,v in d1.items()]
[{'c': 3}, {'a': 1}, {'b': 2}]
複製程式碼

3.字典的轉化

這次我們來看這三個

d1 = {'a': 1, 'b': 2, 'c': 3}
lt = [('a', 1), ('b', 2), ('c', 3)]
ls = [{'a', 1}, {'b', 2}, {'c', 3}]
複製程式碼

後兩個可以直接用dict轉化為字典,但是有些差異

>>> lt = [('a', 1), ('b', 2), ('c', 3)]
>>> dict(lt)
{'c': 3, 'a': 1, 'b': 2}

>>> ls = [{'a', 1}, {'b', 2}, {'c', 3}]
>>> dict(ls)
{1: 'a', 2: 'b', 'c': 3}
複製程式碼

因為ls是以集合為元素的列表,集合是無序,因此轉化為字典時,誰作為鍵誰作為值就不一定了。

d1反過來也是可以轉化為lt ls

>>> d1 = {'a': 1, 'b': 2, 'c': 3}
>>> [tuple(i) for i in d1.items()]
[('c', 3), ('a', 1), ('b', 2)]
>>> [(k, v) for k, v in d1.items()] # 第二種方法
[('c', 3), ('a', 1), ('b', 2)]

>>> [{k, v} for k, v in d1.items()]
[{'c', 3}, {1, 'a'}, {2, 'b'}]
複製程式碼

4.三個列表

接下來看下面三個的對比

lt = [('a', 1), ('b', 2), ('c', 3)]
ls = [{'a', 1}, {'b', 2}, {'c', 3}]
ld1 = [{'a': 1}, {'b': 2}, {'c': 3}]
複製程式碼

這三個都是列表,只是列表的元素分別為元組、集合、字典,它們之間的相互轉化關係也是非常明確的,舉幾個例子

>>> lt = [('a', 1), ('b', 2), ('c', 3)]
>>> ls = [{'a', 1}, {'b', 2}, {'c', 3}]
>>> ld1 = [{'a': 1}, {'b': 2}, {'c': 3}]
>>> [{k, v} for k, v in lt] # lt 到 ls
[{1, 'a'}, {2, 'b'}, {'c', 3}] 
>>> [{k: v} for k, v in lt] # lt 到 ld1
[{'a': 1}, {'b': 2}, {'c': 3}]
>>> [(k, v) for d in ld1 for k, v in d.items()] # ld1 到 lt
[('a', 1), ('b', 2), ('c', 3)]

>>> [(k, v) for k, v in ls]
[(1, 'a'), (2, 'b'), ('c', 3)]
>>> [{k: v} for k, v in ls]
[{1: 'a'}, {2: 'b'}, {'c': 3}]
複製程式碼

可以看到ls無法很好地轉化為其他兩個,因為集合內部元素是無序的。

就對比到這裡了,如果有小夥伴想到更有趣的巢狀方式,歡迎在評論區留言!

歡迎關注我的知乎專欄

專欄主頁:python程式設計

專欄目錄:目錄

版本說明:軟體及包版本說明

相關文章