python 集合(set)和字典(dictionary)的用法解析


Table of Contents generated with DocToc

ditctaionary and set

hash 介紹

  hash是計算機中非常常見一種查找的手法,它可以支持常數時間的insert、remove、find,但是對於findMin、findMax、sort等操作就支持的不是很好,具體是為什么呢;

  hash其實是通過key來找value的,可以這樣簡單的理解為value都被存在一個數組之中,每次你用key計算一下可以得到相應數組的下標,即 index=f(key) 是不是一下子就找到元素所在位置了呢!

集合-set

  集合(set)是一類容器,元素沒有先后順序,並且元素的值不重復。
  集合的字面量用花括號{}
eg:

  • {1,5,7}
  • {'apple', 'orange', 'pear', 'banana'}

創建

  • 直接給變量賦值一個集合字面量
    fruit = {'apple', 'orange', 'pear', 'banana'}

  • 使用set()創建一個空集合
    emp = set()
    注:emp = {} #創建一個空字典

  • 使用set()將列表或元組轉換成集合
    prime = set([1,3,5,7,11])
    結果是:
    {1, 3, 5, 7, 11}

操作和訪問集合的元素

可以用add()和remove()添加和刪除集合元素
可以用min()、max()、len()和sum()對集合操作。
集合內的元素是無序的,所以不能像列表那樣通過下標來訪問集合元素。

  • 用循環實現遍歷集合中的各個元素
s = {2,3,5,7,11}
for i in s:
    print(i,end='')
#輸出:
#235711
  • 運算符in和not in 用於判斷某個元素是否在集合中。
s = {2,3,5,7,11
print(5 in s)
print(4 not in s)
輸出:
True
True

子集、超集、相對判斷

  • 如果集合s1中的元素,同樣都在集合s2中,則稱s1為s2的子集,s2為s1的超集。
    使用s1.issubset(s2)來判斷s1是否為s2的子集。
    使用s2.issuperset(s1)來判斷s1是否為s2的超集。
s1 = {2,3,5,7}
s2 = {1,2,3,4,5,6,7}
print(s1.issubset(s2))
print(s2.issuperset(s1))
輸出:
True
True
  • 使用關系運算符==和!=
    - 判斷2個集合包含的元素完全相同與否。

  • 使用關系運算符<,<=,>,>=。
    - 如果s1是s2的真子集,則s1<s2是True
    - 如果s1是s2的子集,則s1<=s2是True
    - 如果s1是s2的真超集,則s1>s2是True
    - 如果s1是s2的超集,則s1>=s2是True
    - 注:s1是s2的真子集的意思是s1是s2的子集,但是s2中至少有一個s1中不存在的元素; s1是s2的真超集的意思是s1是s2的超集,但是s1中至少有一個s2中不存在的元素。

  • 通過集合的函數或運算符進行集合的並集、交集、差集和對稱差的集合運算。

運算 函數 運算符 說明
並集 union() | 同數學中的並集
交集 intesection() & 同數學交集
差集 difenrence() - s1-s2出現在s1不出現在s2
對稱差 symmertric_diference() ^ s1^s2=s1

字典-dictionary (map)

  字典是一個用“鍵”做索引來存儲的數據的集合。一個鍵和它所對應的數據形成字典中的一個條目。字典的key是用來做hash運算的,需要不可變對象,如數字、字符串、元組;可變的對象不可以作為key,如list、dictionary、set

創建字典

  • 用花括號{ } 來表示,每個元素用冒號分隔鍵和數據。可以用{}或者dict()來創建空字典。
students = {3180101:’張三’, 3180102:’李四’, 3180105:’王五’, 3180110:’趙六’}
d={'math': '0001', 'python': '0002', 'c': '0003'}

d=dict([("math","0001"),("python","0002"),("c","0003")])

d=dict(math="0001",python="0002",c="0003")

字典的基本運算

  • 訪問和修改條目
    直接用[ ]運算符,用<字典> [鍵]的形式,訪問鍵所對應的數據。
score = {'張三':78, '李四':92}
print(score['張三'])#訪問score中鍵為'張三'的數據
score['李四'] = 89#把score中鍵為'李四'的數據修改為89
score['王五'] = 100#score中沒有鍵為‘王五’的元素,則增加一項,鍵為’王五’,數據為100。
print(score)
輸出:
78
{'張三': 78, '李四': 89, '王五': 100}
  • 刪除條目
    del dictName[key]
    如果key不存在,會拋出KeyError異常

  • 遍歷字典

# 循環
score = {'張三':78, '李四':92, '王五':89}
for name in score:
    print(name + ':' + str(score[name]))

#用items()
for key,value in score.items():
   print(key + ':' + str(value))
輸出:
張三:78
李四:92
王五:89
  • 字典的大小len()

  • 檢測,in 和not in檢測key是否在字典中

  • 用==和!=比較2個字典是否相同(鍵和值都相同)

  • 字典常用函數

函數 說明
keys() 返回由全部key組成的序列
values() 返回由全部值組成的序列
items() 返貨一個序列,每一項都是一個tuple,(key,value)
clear() 刪除所有條目
get(key,value) 返回這個鍵所對應的值,如找不到返回value
pop(key) 返回這個鍵所對應的值,同時刪除這個條目

可變對象和不可變對象

可變對象和不可變對象是Python語言的核心概念。

  • 不可變對象,該對象所指向的內存中的值不能被改變。當改變某個變量時候,由於其所指的值不能被改變,相當於把原來的值復制一份后再改變,這會開辟一個新的地址,變量再指向這個新的地址。
  • 可變對象,該對象所指向的內存中的值可以被改變。變量(准確的說是引用)改變后,實際上是其所指的值直接發生改變,並沒有發生復制行為,也沒有開辟新的出地址。
  • 不可變數據類型創建不可變對象,可變數據類型創建可變對象
  • 可變類型有:列表、集合、字典
  • 不可變類型有:整數、浮點數、復數、字符串、邏輯量(True False)、元組
  • 不同數據類型對象和邏輯值的變換
    數據類型 True False
    整數 非0 0
    浮點數 非0 0.0
    復數 非0 0+0j
    字符串 非空 ""
    邏輯量 True False
    列表 非空 []
    元組 非空 ()
    集合 非空 set()
    字典 非空 {}

應用

set

  • 列表去重
#去重,但不能保證保持原有順序
mailto = ['cc', 'bbbb', 'afa', 'sss', 'bbbb', 'cc', 'shafa']
addr_to =list(set(mailto))
print(addr_to)
#result ['shafa', 'cc', 'sss', 'afa', 'bbbb']
#排序后保證保持原有順序
addr_to.sort(key = mailto.index)
print(addr_to)
#result ['cc', 'bbbb', 'afa', 'sss', 'shafa']

找鞍點

n=int(input())
a=[]
for i in range(0,n):
      b=input().split()
      a.insert(i,b)
c=[]
d=[]
for i in range(0,n):
    maxa=max(int(a[i][j]) for j in range(n))
    mina=min(int(a[k][i]) for k in range(0,n))
    c+=[(i,j) for j in range(n) if int(a[i][j])==maxa]
    d+=[(k,i) for k in range(n) if int(a[k][i])==mina]
c=list(set(c)&set(d))
if (c!=[]):
   print(c[0])
else:
   print("NONE")

dictionary

  • 字典替代分支語言
#輸入一個1到7的數字,輸出對應的星期名的縮寫
days={1:"Mon",2:"Tue",3:"Wed",4:"Thu",5:"Fri",6:"Sat",7:"Sun"}
num=int(input())
print(days[num])

result={"+":"x+y","-":"x-y","*":"x*y","/":'''x/y if y!=0   \
        else "divided by zero"'''}
x=int(input())
z=input().strip()
y=int(input())
r=eval(result.get(z))#計算表達式的值
if type(r)!=str:
    print(format(r,'.2f'))
else:
    print(r)

  • 字典計數

eg:1

#輸入一行字符,求字符”a”,”b”和”c”出現的次數

diccount={char:0 for char in "abc"}   #字典初始化
s=input()
lst=[char for char in s if  
      ord("a")<=ord(char)<=ord("c")]
for char in lst:
    diccount[char]+=1
print(diccount)

eg2:

#輸入一行字符,求每個字符出現的次數
#建字典dicchar,鍵是字符,值是字符出現的次數。由於不能預知出現哪些字符,所以不能預先初始化字典
#注意字典的get函數:get() 函數返回指定鍵的值,如果值不在字典中返回默認值。countchar.get(c,0)函數返回鍵為c的值, 不在字典中返回0。

str=input()
countchar={}

for c in str:
    countchar[c]=countchar.get(c,0)+1
print(countchar)

eg:

#求列表中兩數之和等於指定數的下標
'''
Given nums = [2, 11,7, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 2].
'''
nums = [2, 6, 11, 15,7,8]
target = 9


hm = dict()
for i in range(len(nums)):
    if nums[i] in hm:
        print(hm[nums[i]], i)
        break
    hm[target - nums[i]] = i
print([2, 6, 11, 15,7,8])
print(hm)
  • 字典列表嵌套
books=[
        {"name":u"C#從入門到精通","price":25.7,"store":u"卓越"},
        {"name":u"ASP.NET高級編程","price":44.5,"store":u"卓越"},
        {"name":u"Python核心編程","price":24.7,"store":u"當當"},
        {"name":u"JavaScript大全","price":45.7,"store":u"當當"},
        {"name":u"Django簡明教程","price":26.7,"store":u"新華書店"},
        {"name":u"深入Python","price":55.7,"store":u"新華書店"},
      ]

print(min([item["price"] for item in books ]))
#24.7
books[0]['name']
#C#從入門到精通
  • 字典嵌套
users = {'aeinstein': {'first': 'albert',
                       'last': 'einstein',
                       'location': 'princeton'},
         'mcurie': {'first': 'marie',
                    'last': 'curie',
                    'location': 'paris'},
         }

for username, user_info in users.items():
    print("\nUsername: " + username)
    full_name = user_info['first'] + " " + user_info['last']
    location = user_info['location']

    print("\tFull name: " + full_name.title())
    print("\tLocation: " + location.title())
    '''
Username: aeinstein
Full name: Albert Einstein
Location: Princeton

Username: mcurie
Full name: Marie Curie
Location: Paris
    '''
  • 圖和字典
# %% 求圖的頂點數,邊數,邊的總長  空字典{},空集合 set()
d={"start": {1:1,2:2,3:4},  #第一個點為“start”,一條邊指向1,長度為1,一條指向2,長度為2,一條指向3,長度為4
   1:{3:5},
   2:{"end":8,3:78},
   3:{2:4,"end":8},
   "end":{}   }
v=set();     e=set()    ;s=0           #頂點的集合,邊點的集合
for key,value in d.items():
    v.add(key)
    if type(value)==dict:
        for key1,value1 in value.items():
            v.add(key1)
            e.add((key,key1))
            s+=value1

print(len(v),len(e),s)
#5 8 110
  • 組裝字典
id = "IAD"
location = "Dulles Intl Airport"
max_temp = 32
min_temp = 13
precipitation = 0.4


print("{id:3s} : {location:19s} : {max_temp:3d} / {min_temp:3d} /{precipitation:5.2f}".format(
   id=id, location=location, max_temp=max_temp,
   min_temp=min_temp, precipitation=precipitation))

data = dict(
       id=id, location=location, max_temp=max_temp,
       min_temp=min_temp, precipitation=precipitation
       )
print("{id:3s} : {location:19s} : {max_temp:3d} / {min_temp:3d} /{precipitation:5.2f}".format_map(data))

#IAD : Dulles Intl Airport :  32 /  13 / 0.40
#IAD : Dulles Intl Airport :  32 /  13 / 0.40
#date={'id': 'IAD', 'location': 'Dulles Intl Airport', 'max_temp': 32, 'min_temp': 13, 'precipitation': 0.4}

參考文檔

[python官方文檔]https://docs.python.org/3.8/library/stdtypes.html#set-types-set-frozenset

注:如有侵權聯系作者刪帖


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM