文章目錄
- 一、串列
- 1.創建串列
- 2.洗掉元素
- 3.添加元素
- 4.串列排序
- 5.串列賦值
- 6.串列推導式
- 二、元組
- 1.元組基本操作
- 2.元組和串列的對比
- 三、字典
- 1.創建字典
- 2.訪問字典
- 3.更新字典
- 4.洗掉字典
- 四、集合
- 1.創建集合
- 2.集合運算
- 五、資料結構型別轉換
- 1.轉化為串列
- 2.轉化為字典
- 3.zip
- 4.Mutable和Immutable
- 5.遍歷序列資料結構
一、串列
之前的資料型別一般都是單個值,而不能再存盤像矩陣、陣列這種結構存盤多個元素,要是需要達到這樣的目標、需要使用新的資料型別,Python中提供了4種資料結構來存盤多個物件,稱它們為容器型別(Container Types),包括如下幾種型別:
- 串列List
- 元組Tuple
- 字典Dictionary
- 集合Set
1.創建串列
其實,字串其實也是一種序列,是由字符組成的序列,
字串可以通過切片訪問部分元素:
# sequence of characters
s="Corley!"
s[2:4]
輸出:
'rl'
如需本節同步
ipynb檔案,可以直接點擊加QQ群963624318 在群檔案夾商業資料分析從入門到入職中下載即可,
字串是一個字符序列,串列是一個物件的序列,當物件的順序很重要時就會使用串列,
創建和訪問串列如下:
#sequence of anything
p = ['C','o','r','l','e','y','!']
p[2:4]
輸出:
['r', 'l']
可以看到,串列是用[]定義的,元素放入其中,用,隔開,
再如:
def how_many_days(month):
days_in_month=[31,28,31,30,31,30,31,31,30,31,30,31]
return days_in_month[month-1]
display(how_many_days(2), how_many_days(5), how_many_days(10))
輸出:
28
31
31
可以看到,直接獲取到了2、5、8月的天數,
還可以直接創建空串列,如下:
empty_list = []
another_empty_list = list()
display(empty_list,another_empty_list)
輸出:
[]
[]
可以看到,輸出了兩個空串列,
還可以從字串中分割出串列,如下:
weekday_str = 'Monday,Tuesday,Wednesday,Thursday,Friday'
weekdays = weekday_str.split(',')
weekdays
輸出:
['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
以串列作為元素創建串列如下:
obj_list = ["string", 1, True, 3.14]
list_of_list = [empty_list, weekdays, obj_list]
list_of_list
輸出:
[[],
['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
['string', 1, True, 3.14]]
此即串列的嵌套,
再如:
dal_memeber= [['Corley',18],['Jack',18],['Shirely',48],['Tom',18]]
print(dal_memeber)
print(dal_memeber[0])
print(dal_memeber[0][1])
輸出:
[['Corley', 18], ['Jack', 18], ['Shirely', 48], ['Tom', 18]]
['Corley', 18]
18
串列可以定位和切片如下:
display(weekdays[0],weekdays[1:3])
輸出:
'Monday'
['Tuesday', 'Wednesday']
還可以通過賦值改變串列中的元素,如下:
weekdays[0] = "Sunday"
weekdays
輸出:
['Sunday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
顯然,第一個元素已經改變,
2.洗掉元素
還可以洗掉串列中的元素,
一種方式是使用del關鍵字,基于下標洗掉,如下:
del weekdays[0]
weekdays
輸出:
['Tuesday', 'Wednesday', 'Thursday', 'Friday']
顯然,第一個元素被洗掉,
再如:
al = ['A', 'B', 'C', 'D', 'E', 'F', 'G']
del al[3:]
al
輸出:
['A', 'B', 'C']
一次性洗掉多個元素,
還有一種方式是使用remove()方法,基于元素洗掉,
如下:
weekdays.remove('Friday')
weekdays
輸出:
['Tuesday', 'Wednesday', 'Thursday']
但是如果串列中不存在這個元素時,會報錯,如下:
weekdays.remove('Friday')
weekdays
報錯:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-20-b508ecb8e563> in <module>
----> 1 weekdays.remove('Friday')
2 weekdays
ValueError: list.remove(x): x not in list
因為weekdays中沒有元素'Friday',因此會報錯,
此時可以先進行判斷,如果元素存在于串列中則洗掉,否則不洗掉;
判斷一個元素是否存在于串列中可以用in關鍵字,存在則回傳True,否則回傳False,
如下:
if 'Friday' in weekdays:
weekdays.remove('Friday')
else:
print('element not exists')
輸出:
element not exists
in的用法再如:
weekdays = ['Monday','Tuesday','Wednesday','Thursday','Friday']
'Friday' in weekdays
輸出:
True
還可以判斷某個元素是否不在串列中,如下:
'Fri' not in weekdays
輸出:
4
5
除了使用del和remove()洗掉元素,也可以使用pop()彈出元素,該方法不僅可以彈出元素,還能回傳被彈出的元素,如果未傳遞引數,則默認彈出并回傳最后一個元素,傳遞了下標引數則彈出并回傳相應的元素,
如下:
seasons = ['spring', 'summmer', 'autumn', 'winter']
last_season = seasons.pop()
print("last_season = ", last_season, "\nseasons = ", seasons)
輸出:
last_season = winter
seasons = ['spring', 'summmer', 'autumn']
再如:
first_season = seasons.pop(0)
print("first_season = ", first_season, "\nseasons = ", seasons)
輸出:
first_season = spring
seasons = ['summmer', 'autumn']
3.添加元素
向串列中添加元素也有多種方式:
一種是使用append()方法,該方法是將元素添加到串列末尾,
如下:
weekdays.append('Friday')
weekdays
輸出:
['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Friday']
可以看到,串列中允許出現重復元素,
一種是insert()方法,可以指定位置添加元素,
如下:
weekdays.insert(0, 'Monday')
weekdays
輸出:
['Monday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Friday']
兩個串列也可以直接相加、形成新的串列,
如下:
weekend = ['Saturday', 'Sunday']
weekdays = weekdays + weekend
weekdays
輸出:
['Monday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Friday',
'Saturday',
'Sunday']
還可以根據元素獲取其再在串列中的下標位置:
display(weekdays.index('Thursday'),weekdays.index('Friday'))
輸出:
4
5
可以看到,有重復元素時,會回傳第一個下標,
4.串列排序
串列可以按照元素的大小進行排序:
串列方法sort()對串列本身進行原地排序;
通用函式sorted()回傳串列的已排序副本,
如下:
nums = [1,4,2,5,3]
sorted_nums = sorted(nums)
print("nums =", nums, "\nsorted_nums =", sorted_nums)
輸出:
nums = [1, 4, 2, 5, 3]
sorted_nums = [1, 2, 3, 4, 5]
可以看到,nums串列經過排序并傳遞給sorted_nums,
再如:
nums.sort()
nums
輸出:
[1, 2, 3, 4, 5]
直接對串列本身排序;
同時,默認為升序,
還可以進行降序排序,指定引數reverse=True即可:
sorted_nums = sorted(nums, reverse=True)
nums.sort(reverse=True)
display(sorted_nums, nums)
輸出:
[5, 4, 3, 2, 1]
[5, 4, 3, 2, 1]
還可以對字串進行排序:
str_ls = ['apple', 'pear', 'lemon', 'peach']
str_ls.sort()
str_ls
輸出:
['apple', 'lemon', 'peach', 'pear']
可以看到:
對字串進行排序時,首先根據首字母排序,如果首字母相同,再根據下一個字母排序,依此類推,
串列的方法sort()是對串列本身進行排序,回傳值為None;
通用函式sorted()對包括串列在內的可迭代物件排序,回傳一個排好序的新串列,
如下:
display(sorted('joshuazhao1234'),''.join(sorted('ACBDZYX')))
輸出:
['1', '2', '3', '4', 'a', 'a', 'h', 'h', 'j', 'o', 'o', 's', 'u', 'z']
'ABCDXYZ'
join()方法是以傳入的引數為分隔符拼接串列元素,
但是不能對不同型別的資料進行排序,
如下:
obj_list = ["string",1, True, 3.14]
obj_list.sort()
obj_list
會報錯:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-8-18b4b015f0f5> in <module>
1 obj_list = ["string",1, True, 3.14]
----> 2 obj_list.sort()
3 obj_list
TypeError: '<' not supported between instances of 'int' and 'str'
但是整型和浮點型之間可以進行排序,如下:
obj_list = [1, 3.14]
obj_list.sort()
obj_list
輸出:
['1', '2', '3', '4', 'a', 'a', 'h', 'h', 'j', 'o', 'o', 's', 'u', 'z']
'ABCDXYZ'
5.串列賦值
將串列型別變數賦值給新的變數:
#assign vs copy
a = [1,2,3]
b = a
print("a = ", a, "\nb = ", b)
print()
a[0] = 2
print("a = ", a, "\nb = ", b)
print()
b[1] = 3
print("a = ", a, "\nb = ", b)
輸出:
a = [1, 2, 3]
b = [1, 2, 3]
a = [2, 2, 3]
b = [2, 2, 3]
a = [2, 3, 3]
b = [2, 3, 3]
可以看到,在a發生改變之后,b也發生了改變,同時b發生改變之后,a也發生了改變;
這是發生了淺復制,只是將a對應的串列所指向的地址賦值給b,即a、b都指向同一個地址,所以串列改變a、b對應的值都會改變,
對串列進行賦值和創建串列還有其他一些操作:
a = [1,2,3]
b = a
c = a.copy()
d = a[:]
e = list(a)
print("a = ", a, "\nb = ", b, "\nc = ", c, "\nd = ", d, "\ne = ", e)
print()
a[0] = 2
print("a = ", a, "\nb = ", b, "\nc = ", c, "\nd = ", d, "\ne = ", e)
輸出:
a = [1, 2, 3]
b = [1, 2, 3]
c = [1, 2, 3]
d = [1, 2, 3]
e = [1, 2, 3]
a = [2, 2, 3]
b = [2, 2, 3]
c = [1, 2, 3]
d = [1, 2, 3]
e = [1, 2, 3]
可以看到,只有直接賦值b = a才會是淺復制,與原陣列是同一個陣列、同步變化;
其他方法都是通過a陣列產生了一個新陣列,與原陣列不會同步變化,
6.串列推導式
Python支持串列推導式,它可以用一種非常自然、簡單的方式來構造串列,就像數學家經常做的那樣,
其定義格式為[expression for item in iterable],
通常,定義一個從0到9的數字串列可能如下:
num_list = []
for i in range(0, 10):
num_list.append(i)
num_list
輸出:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
但是還可以有更優雅的實作方式,如:
num_list = list(range(0,10))
num_list
但是還可以進一步優化,即使用串列推導式,如下:
num_list = [i for i in range(0, 10)]
num_list
輸出與之前相同;
可以看到,串列推導式可以從一個舊的序列生成一個新的串列,
再如:
num_list = [i**2 for i in range(0, 10)]
num_list
可以生成0-9的平方的串列,
還可以對序列元素進行條件判斷、過濾生成新串列,即帶條件的串列推導式,格式為[expression for item in iterable if condition],
例如創建一個從0到9的奇數串列,如下:
num_list = []
for i in range(0, 10):
if i % 2 == 1:
num_list.append(i)
num_list
輸出:
[1, 3, 5, 7, 9]
還可以使用如下方式:
num_list = list(range(1,10,2))
num_list
更簡單的方式還是使用帶條件的串列推導式,如下:
num_list = [i for i in range(0,10) if i % 2 == 1]
num_list
再如:
import math
num_list = [i * i for i in range(0,int(math.sqrt(500))) if i % 3 == 2]
num_list
輸出:
[4, 25, 64, 121, 196, 289, 400]
串列推導式還可以用于將一個串列分成兩個串列,一個串列中所有數字都低于分割元素,另一個串列包含所有大于或等于分割元素,
如下:
import random
num_list = random.sample(range(10), 10)
target = 5
print("list =",num_list)
print("target =", target)
l1 = [x for x in num_list if x < target]
l2 = [x for x in num_list if x >= target]
print("l1:", l1)
print("l2:", l2)
輸出:
list = [0, 5, 8, 4, 1, 6, 9, 2, 3, 7]
target = 5
l1: [0, 4, 1, 2, 3]
l2: [5, 8, 6, 9, 7]
其中,l2也可以通過以下方式獲得:
l2 = [x for x in num_list if x not in l1]
print("l2:", l2)
不使用串列推導式實作嵌套定義多維陣列或矩陣,如下:
rows = range(1,4)
cols = range(1,3)
cells = []
for row in rows:
for col in cols:
cells.append((row, col))
cells
輸出:
[(1, 1), (1, 2), (2, 1), (2, 2), (3, 1), (3, 2)]
如果要使用串列推導式,需要使用嵌套,如下:
cells = [(r, c) for r in rows for c in cols]
cells
輸出相同,
二、元組
與串列類似,元組也是任意項的序列,
然而,元組是不可變的,定義后不能增加、洗掉或更改,
1.元組基本操作
創建一個空元組如下:
empty_tuple = ()
empty_tuple
輸出:
()
創建一個不為空的串列:
week_tuple = ('Monday', 'Tuesday')
week_tuple
輸出:
('Monday', 'Tuesday')
還可以通過下面的方式創建:
tpl = 123,456,789
tpl
輸出:
(123, 456, 789)
在實際生活中,123,456,789就是一個九位數,每3位用逗號分割,但是Python中成為了長度為3的元組,
訪問元素的方式和串列類似,如下:
display(week_tuple[1], tpl[2])
輸出:
'Tuesday'
789
要創建只有一個元素的元組,不能直接用括號將元素括起來,還應該在這個元素后面加1個逗號,,
如下:
single_tuple1 = ('Monday',)
single_tuple2 = ('Monday')
display(type(single_tuple1), type(single_tuple2))
輸出:
tuple
str
可以看到,直接用括號括起來的一個元素就相當于其元素本身,并未形成串列,
串列和元組都支持一次性將元素賦值給個數與元素個數相等的變數如下:
tom_list = ['Tom', 'Male', 20]
name, gender, age = tom_list
print("Name = ", name, "\nGender = ", gender, "\nAge = ", age)
tom_tuple = ('Tom', 'Male', 20)
name, gender, age = tom_tuple
print("Name = ", name, "\nGender = ", gender, "\nAge = ", age)
輸出:
Name = Tom
Gender = Male
Age = 20
Name = Tom
Gender = Male
Age = 20
此時就可以不用再單個賦值、提高了效率,
元組可以用于交換兩個變數的值,
如下:
a = 1
b = 2
print("a = ", a, ", b = ", b)
a, b = b, a
print("a = ", a, ", b = ", b)
輸出:
a = 1 , b = 2
a = 2 , b = 1
2.元組和串列的對比
與串列相比,元組有以下特點:
(1)元組使用更少的空間(動態);
(2)不能錯誤地破壞元組項,即不能改變元素,元組屬于不可變型別;
(3)可以用元組作為字典的鍵;
(4)函式引數作為元組傳遞,
元組不能進行修改,
如下:
week_tuple[1] = 'Thursday'
week_tuple
報錯:
TypeError Traceback (most recent call last)
<ipython-input-24-4df244291e3f> in <module>
----> 1 week_tuple[1] = 'Thursday'
2 week_tuple
TypeError: 'tuple' object does not support item assignment
但是可以通過使用原元組生成新的元組,
如下:
tpl2 = week_tuple[0], 2
tpl2
輸出:
('Monday', 2)
可以看到,通過使用原元組的元素,生成了新的元組,
三、字典
字典類似于串列,但是專案的順序并不重要,它們不會根據偏移量(索引)進行選擇,
相反,您可以指定一個與每個值關聯的唯一鍵,
鍵通常是一個字串,但它可以是Python的任何不可變型別,
字典就像實際生活中的字典,根據索引來查找元素,而不是通過下標,
1.創建字典
創建一個空字典如下:
empty_dict = {}
empty_dict
輸出:
{}
創建一個包含元素的字典,如下:
pizza = {
"size":"medium",
"type":"pepperoni",
"crust":"Thick",
"qty": 1,
"deliver":True,
}
pizza
輸出:
{'size': 'medium',
'type': 'pepperoni',
'crust': 'Thick',
'qty': 1,
'deliver': True}
可以看到,該元組共有5個鍵值對;
其中,'size': 'medium'就是一個鍵值對,'size'是鍵,'medium'是值,
創建字典時,鍵重復時就會覆寫:
pizza = {
"size":"small",
"size":"medium",
"type":"pepperoni",
"crust":"Thick",
"qty": 1,
"deliver":True,
}
pizza
輸出:
{'size': 'medium',
'type': 'pepperoni',
'crust': 'Thick',
'qty': 1,
'deliver': True}
可以看到,鍵重復時,只會保留后面的值,前面的都會被覆寫,
2.訪問字典
訪問字典時,是根據鍵訪問對應的值,
如下:
print(pizza['type'])
輸出:
pepperoni
如果訪問未定義的鍵,就會報錯:
print(pizza['topping'])
報錯:
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-31-ca25624dca51> in <module>
----> 1 print(pizza['topping'])
KeyError: 'topping'
此時可以使用get()方法訪問元素,因為如果不存在對應的鍵時,不會報錯而是回傳空:
display(pizza.get('type'),pizza.get('topping'))
輸出:
'pepperoni'
None
可以看到,此時如果未訪問到元素時不會報錯,回傳了None,
還可以獲取字典中的所有鍵、所有值和所有鍵值對,
如下:
display(pizza.keys(),pizza.values(),pizza.items())
輸出:
dict_keys(['size', 'type', 'crust', 'qty', 'deliver'])
dict_values(['medium', 'pepperoni', 'Thick', 1, True])
dict_items([('size', 'medium'), ('type', 'pepperoni'), ('crust', 'Thick'), ('qty', 1), ('deliver', True)])
3.更新字典
更新字典可以直接給對應的鍵賦值即可,
如下:
pizza['topping'] = ['cheese','mushroom']
pizza
輸出:
{'size': 'medium',
'type': 'pepperoni',
'crust': 'Thick',
'qty': 1,
'deliver': True,
'topping': ['cheese', 'mushroom']}
上面是添加鍵值對,也可以修改鍵值對中的值,
如下:
pizza['qty'] = 10
pizza
輸出:
{'size': 'medium',
'type': 'pepperoni',
'crust': 'Thick',
'qty': 10,
'deliver': True,
'topping': ['cheese', 'mushroom']}
4.洗掉字典
洗掉字典中的鍵值對使用del關鍵字,
如下:
del pizza['topping']
pizza
輸出:
{'size': 'medium',
'type': 'pepperoni',
'crust': 'Thick',
'qty': 10,
'deliver': True}
還可以直接清空字典,
如下:
pizza.clear()
pizza
輸出:
{}
四、集合
集合和數學中的集合很類似,沒有重復的元素,
集合就像字典,它的值被丟棄,只留下鍵,
1.創建集合
可以創建一個空集合:
empty_set = set()
empty_set
輸出:
set()
創建非空的集合如下:
even_set = {2,4,6,6,8,10}
even_set
輸出:
{2, 4, 6, 8, 10}
可以看到,重復的元素被合并,只保留一個元素,因此集合中不存在重復元素,
2.集合運算
集合的運算包括了數學中對集合的運算,如并集、交集、差集等,
如下:
num_set = {3,6,9,12,15,18}
display(num_set & even_set, num_set | even_set, num_set - even_set, even_set - num_set, even_set ^ num_set,(even_set | num_set) - (even_set & num_set))
輸出:
{6}
{2, 3, 4, 6, 8, 9, 10, 12, 15, 18}
{3, 9, 12, 15, 18}
{2, 4, 8, 10}
{2, 3, 4, 8, 9, 10, 12, 15, 18}
{2, 3, 4, 8, 9, 10, 12, 15, 18}
五、資料結構型別轉換
1.轉化為串列
可以將字串、元組、字典、集合等資料結構轉化為串列,
如下:
display(list('ababc'),list((1,2,3,4)),list({'name': 'Ed', 'employer': 'Oracle'}),list({'name': 'Ed', 'employer': 'Oracle'}.values()),sorted(list({5,6,7,8})))
輸出:
['a', 'b', 'a', 'b', 'c']
[1, 2, 3, 4]
['name', 'employer']
['Ed', 'Oracle']
[5, 6, 7, 8]
可以看到,在對字典進行轉化為串列時,默認使用的是鍵,可以通過呼叫values()獲取到值再進行轉化;
元組轉換與串列轉換相同;
在將字典或集合轉換為串列時,不能保持字典或集合的順序,
2.轉化為字典
轉化為字典,需要有成對出現的元素,來保證可以組成鍵值對,否則不能進行正常轉換,
如一般的字串就不能轉化為字典,如下:
dict('ababc')
報錯:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-47-f82ea82e76c5> in <module>
----> 1 dict('ababc')
ValueError: dictionary update sequence element #0 has length 1; 2 is required
普通串列轉換也會報錯,如下:
dict([1,2,3])
報錯:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-48-e308b22febdd> in <module>
----> 1 dict([1,2,3])
TypeError: cannot convert dictionary update sequence element #0 to a sequence
有成對出現的資料,即元素的長度為2,就可以進行正常轉換,
如下:
dict(['ab', 'cd', 'ef'])
輸出:
{'a': 'b', 'c': 'd', 'e': 'f'}
可以看到,此時因為串列是由長度為2的字串組成的,因此可以將第1個字符作為鍵,第2個字符作為值
再如:
dict([['a', 'b'], ('c', 'd'), ('e', 'f')])
輸出:
{'a': 'b', 'c': 'd', 'e': 'f'}
可以總結出:
在轉化成字典時,被轉化的物件必須是序列,并且序列中的每個元素長度為2,
3.zip
zip()函式可以將兩個或多個序列生成對應位置元素生成元組作為元素的新序列,
如下:
s1 = 'abcdefg'
s2 = 'hijklmn'
list(zip(s1, s2))
輸出:
[('a', 'h'),
('b', 'i'),
('c', 'j'),
('d', 'k'),
('e', 'l'),
('f', 'm'),
('g', 'n')]
如果兩個序列的長度不一致時,會以長度較短的序列為準,
還可以將合成后的序列拆分成原來的序列,如下:
s3, s4 = zip(*d)
print(list(s3))
print(list(s4))
輸出:
['a', 'b', 'c', 'd', 'e', 'f', 'g']
['h', 'i', 'j', 'k', 'l', 'm', 'n']
可以使用相同的函式進行解壓縮,只需要在變數前面加一個*即可實作,
4.Mutable和Immutable
Python中資料型別的可變與不可變是通過Mutable和Immutable來控制的:
Mutable即可變型別,包括串列、字典和集合等,還包括自定義的型別,如果需要將其定義為不可變型別,需要重寫object的__setattr__和__delattr__方法;
Immutable即不可變型別,包括整型、浮點型、布爾型、字串和元組等,
如下:
s='hello'
print("{} id is {}".format(s,id(s)))
s='Yello'
print("{} id is {}".format(s,id(s)))
s= s+'w'
print("{} id is {}".format(s,id(s)))
輸出:
hello id is 3116696357488
Yello id is 3116695670320
Yellow id is 3116696394800
其中,id()用于獲取一個變數在記憶體中的地址,唯一標識一個變數,在變數重新賦值、發生改變之后,就成為一個新的變數,地址也發生改變,
對于整數來說,情況相同,如下:
i=1
print("{} id is {}".format(i,id(i)))
i=10
print("{} id is {}".format(i,id(i)))
i=10+1
print("{} id is {}".format(i,id(i)))
輸出:
1 id is 140709660735264
10 id is 140709660735552
11 id is 140709660735584
對于不可變的變數,不能進行修改,否則會報錯:
s = 'hello'
s[0] = 'b'
報錯:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-57-ee36c369d295> in <module>
1 s = 'hello'
----> 2 s[0] = 'b'
TypeError: 'str' object does not support item assignment
這在有時候會帶來一些問題,
對于可變型別,參考呼叫(call by reference) 如下:
try_result=[] #cold refresh
def try_func(arg,result):
print("inside before result is labeled {}, value {}".format(id(result),result))
result.append(arg)
print("inside after result is labeled {}, value {}".format(id(result),result))
print("inside try_result is labeled {}, value is {}".format(id(try_result),try_result))
print("before try_result is labeled {}, value is {}".format(id(try_result),try_result))
try_func('a',try_result)
print("after try_result is labeled {}, value is {}".format(id(try_result),try_result))
try_result.append('b')
print(try_result)
try_func('a',try_result)
輸出:
before try_result is labeled 3116696770752, value is []
inside before result is labeled 3116696770752, value []
inside after result is labeled 3116696770752, value ['a']
inside try_result is labeled 3116696770752, value is ['a']
after try_result is labeled 3116696770752, value is ['a']
['a', 'b']
inside before result is labeled 3116696770752, value ['a', 'b']
inside after result is labeled 3116696770752, value ['a', 'b', 'a']
inside try_result is labeled 3116696770752, value is ['a', 'b', 'a']
此時,try_result是以全域變數的形式定義的;
并且,在整個程序中,因為串列是可變型別,雖然值發生了變化,但是id即地址并沒有改變,
而對于不可變型別,值傳遞(pass by value) 如下:
imu_number = 10
def updateNumber(number):
print("inside number is labeled {}, value {}".format(id(number),number))
print("inside imu_number is labeled {}, value {}".format(id(imu_number),imu_number))
number = 20
print("inside number is {}, outside imu_number is {}".format(number,imu_number))
print("before imu_number is labeled {}, value {}".format(id(imu_number),imu_number))
updateNumber(imu_number)
print("after imu_number is labeled {}, value {}".format(id(imu_number),imu_number))
輸出:
before imu_number is labeled 140709660735552, value 10
inside number is labeled 140709660735552, value 10
inside imu_number is labeled 140709660735552, value 10
inside number is 20, outside imu_number is 10
after imu_number is labeled 140709660735552, value 10
可以看到,在整個程序中imu_number的id都沒有發生變化;
并且在函式內部和外部,imu_number的值也未發生改變,
需要注意:
給引數提供的默認值是在定義函式時計算的,而不是在函式運行時計算的;
盡量不要使用可變資料型別(如串列或字典)作為默認引數,
如下:
def buggy(arg, result=[]):
print(id(result))
result.append(arg)
print(result)
buggy('a')
buggy('b')
輸出:
3116693617856
['a']
3116693617856
['a', 'b']
可以看到,第二次呼叫時串列中已經包含元素'a',因此再依次呼叫會存在兩個元素,這是因為引數默認值只是在定義函式便確定,之后不會再此使用提供的默認值而是經過計算后的值,
要是需要每次都是空串列中添加值,可以通過賦值給引數不可變的型別,如下:
def nonbuggy(arg, result=None):
if result is None:
result = []
print(id(result))
result.append(arg)
print(result)
nonbuggy('a')
nonbuggy('b')
輸出:
3116695253696
['a']
3116696770496
['b']
可以看到,此時執行函式時都是向空串列中添加元素,
5.遍歷序列資料結構
要是需要遍歷一個序列中的元素,可以如下:
weekdays = ['Monday','Tuesday','Wednesday','Thursday','Friday']
i = 0
while i < len(weekdays):
print(weekdays[i])
i +=1
輸出:
Monday
Tuesday
Wednesday
Thursday
Friday
還可以如下:
for i in range(len(weekdays)):
print(weekdays[i])
輸出結果與之前一致,
但是還可以直接用for回圈遍歷序列,如串列可以直接使用for回圈,
如下:
for day in weekdays:
print(day)
輸出結果與前面相同;
顯然,這種方式更加簡單,
還可以使用enumerate()函式對串列對應生成序號,
如下:
for key,day in enumerate(weekdays):
print(str(key)+" "+day)
輸出:
0 Monday
1 Tuesday
2 Wednesday
3 Thursday
4 Friday
字典有更豐富的遍歷方式,
如下:
pizza = {
"size":"medium",
"size":"small",
"type":"pepperoni",
"crust":"Thick",
"qty": 1,
"deliver":True,
}
for k in pizza:
print(k)
print()
for k, v in pizza.items():
print("key is {}, value is {}".format(k,v))
print()
for v in pizza.values():
print(v)
輸出:
size
type
crust
qty
deliver
key is size, value is small
key is type, value is pepperoni
key is crust, value is Thick
key is qty, value is 1
key is deliver, value is True
small
pepperoni
Thick
1
True
可以看到,第一種方式是默認訪問的字典的鍵;
第二種方式訪問鍵值對;第三種方式訪問字典的值,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/135152.html
標籤:其他
上一篇:Python之猜單詞游戲

963624318 在群檔案夾商業資料分析從入門到入職中下載即可,