本文收錄在Python從入門到精通系列文章系列html
第二次世界大戰促使了現代電子計算機的誕生,最初計算機被應用於導彈彈道的計算,而在計算機誕生後的不少年時間裏,計算機處理的信息基本上都是數值型的信息。世界上的第一臺電子計算機叫ENIAC(電子數值積分計算機),誕生於美國的賓夕法尼亞大學,每秒鐘可以完成約5000次浮點運算。隨着時間的推移,雖然數值運算仍然是計算機平常工做中最爲重要的事情之一,可是今天的計算機處理得更多的數據可能都是以文本的方式存在的,若是咱們但願經過Python程序操做這些文本信息,就必需要先了解字符串類型以及與它相關的知識。python
所謂字符串,就是由零個或多個字符組成的有限序列,通常記爲git
在Python程序中,若是咱們把單個或多個字符用單引號或者雙引號包圍起來,就能夠表示一個字符串。windows
s1 = 'hello, world!' s2 = "hello, world!" # 以三個雙引號或單引號開頭的字符串能夠折行 s3 = """ hello, world! """ print(s1, s2, s3, end='')
能夠在字符串中使用\(反斜槓)來表示轉義,也就是說\後面的字符再也不是它原來的意義,例如:\n不是表明反斜槓和字符n,而是表示換行;而\t也不是表明反斜槓和字符t,而是表示製表符。因此若是想在字符串中表示'要寫成\',同理想表示\要寫成\\。能夠運行下面的代碼看看會輸出什麼。api
s1 = '\'hello, world!\'' s2 = '\n\\hello, world!\\\n' print(s1, s2, end='')
在\後面還能夠跟一個八進制或者十六進制數來表示字符,例如\141和\x61都表明小寫字母a,前者是八進制的表示法,後者是十六進制的表示法。也能夠在\後面跟Unicode字符編碼來表示字符,例如\u963f\u9f99表明的是中文「阿龍」。運行下面的代碼,看看輸出了什麼。安全
s1 = '\141\142\143\x61\x62\x63' s2 = '\u963f\u9f99' print(s1, s2)
若是不但願字符串中的\表示轉義,咱們能夠經過在字符串的最前面加上字母r來加以說明,再看看下面的代碼又會輸出什麼。數據結構
s1 = r'\'hello, world!\'' s2 = r'\n\\hello, world!\\\n' print(s1, s2, end='')
Python爲字符串類型提供了很是豐富的運算符,咱們可使用+運算符來實現字符串的拼接,可使用*運算符來重複一個字符串的內容,可使用in和not in來判斷一個字符串是否包含另一個字符串(成員運算),咱們也能夠用[]和[:]運算符從字符串取出某個字符或某些字符(切片運算),代碼以下所示。多線程
s1 = 'hello ' * 3 print(s1) # hello hello hello s2 = 'world' s1 += s2 print(s1) # hello hello hello world print('ll' in s1) # True print('good' in s1) # False str2 = 'abc123456' 從字符串中取出指定位置的字符(下標運算) print(str2[2]) # c # 字符串切片(從指定的開始索引到指定的結束索引) print(str2[2:5]) # c12 print(str2[2:]) # c123456 print(str2[2::2]) # c246 print(str2[::2]) # ac246 print(str2[::-1]) # 654321cba print(str2[-3:-1]) # 45
(1)在Python中,咱們還能夠經過一系列的方法來完成對字符串的處理,代碼以下所示。app
str1 = 'hello, world!' # 經過內置函數len計算字符串的長度 print(len(str1)) # 13 # 得到字符串首字母大寫的拷貝 print(str1.capitalize()) # Hello, world! # 得到字符串每一個單詞首字母大寫的拷貝 print(str1.title()) # Hello, World! # 得到字符串變大寫後的拷貝 print(str1.upper()) # HELLO, WORLD! # 從字符串中查找子串所在位置 print(str1.find('or')) # 8 print(str1.find('shit')) # -1 # 與find相似但找不到子串時會引起異常 print(str1.index('or')) # print(str1.index('shit')) # 檢查字符串是否以指定的字符串開頭 print(str1.startswith('He')) # False print(str1.startswith('hel')) # True # 檢查字符串是否以指定的字符串結尾 print(str1.endswith('!')) # True # 將字符串以指定的寬度居中並在兩側填充指定的字符 print(str1.center(50, '*')) # 將字符串以指定的寬度靠右放置左側填充指定的字符 print(str1.rjust(50, ' ')) str2 = 'abc123456' # 檢查字符串是否由數字構成 print(str2.isdigit()) # False # 檢查字符串是否以字母構成 print(str2.isalpha()) # False # 檢查字符串是否以數字和字母構成 print(str2.isalnum()) # True str3 = ' jackfrued@126.com ' print(str3) # 得到字符串修剪左右兩側空格以後的拷貝 print(str3.strip())
(2)咱們以前講過,能夠用下面的方式來格式化輸出字符串。dom
a, b = 5, 10 print('%d * %d = %d' % (a, b, a * b))
固然,咱們也能夠用字符串提供的方法來完成字符串的格式,代碼以下所示。
a, b = 5, 10 print('{0} * {1} = {2}'.format(a, b, a * b))
Python 3.6之後,格式化字符串還有更爲簡潔的書寫方式,就是在字符串前加上字母f,咱們可使用下面的語法來簡化上面的代碼。
a, b = 5, 10 print(f'{a} * {b} = {a * b}')
除了字符串,Python還內置了多種類型的數據結構,若是要在程序中保存和操做數據,絕大多數時候能夠利用現有的數據結構來實現,最經常使用的包括列表、元組、集合和字典。
不知道你們是否注意到,剛纔咱們講到的字符串類型(str)和以前咱們講到的數值類型(int和float)有一些區別。數值類型是標量類型,也就是說這種類型的對象沒有能夠訪問的內部結構;而字符串類型是一種結構化的、非標量類型,因此纔會有一系列的屬性和方法。
接下來咱們要介紹的列表(list),也是一種結構化的、非標量類型,它是值的有序序列,每一個值均可以經過索引進行標識。
定義列表能夠將列表的元素放在[]中,多個元素用,進行分隔,可使用for循環對列表元素進行遍歷,也可使用[]或[:]運算符取出列表中的一個或多個元素。
01-下面的代碼演示瞭如何定義列表、如何遍歷列表以及列表的下標運算
list1 = [1, 3, 5, 7, 100] print(list1) # [1, 3, 5, 7, 100] # 乘號表示列表元素的重複 list2 = ['hello'] * 3 print(list2) # ['hello', 'hello', 'hello'] # 計算列表長度(元素個數) print(len(list1)) # 5 # 下標(索引)運算 print(list1[0]) # 1 print(list1[4]) # 100 # print(list1[5]) # IndexError: list index out of range print(list1[-1]) # 100 print(list1[-3]) # 5 list1[2] = 300 print(list1) # [1, 3, 300, 7, 100] # 經過循環用下標遍歷列表元素 for index in range(len(list1)): print(index,list1[index]) # 經過for循環遍歷列表元素 for elem in list1: print(elem) # 經過enumerate函數處理列表以後再遍歷能夠同時得到元素索引和值 for index, elem in enumerate(list1): print(index, elem)
02-下面的代碼演示瞭如何向列表中添加元素以及如何從列表中移除元素
list1 = [1, 3, 5, 7, 100] # 添加元素 list1.append(200) print(list1) list1.insert(1, 400) print(list1) # 合併兩個列表 # list1.extend([1000, 2000]) list1 += [1000, 2000] print(list1) # [1, 400, 3, 5, 7, 100, 200, 1000, 2000] print(len(list1)) # 9 # 先經過成員運算判斷元素是否在列表中,若是存在就刪除該元素 if 3 in list1: list1.remove(3) if 1234 in list1: list1.remove(1234) print(list1) # [1, 400, 5, 7, 100, 200, 1000, 2000] # 從指定的位置刪除元素 list1.pop(0) list1.pop(len(list1) - 1) print(list1) # [400, 5, 7, 100, 200, 1000] # 清空列表元素 list1.clear() print(list1) # []
和字符串同樣,列表也能夠作切片操做,經過切片操做咱們能夠實現對列表的複製或者將列表中的一部分取出來建立出新的列表,代碼以下所示。
fruits = ['grape', 'apple', 'strawberry', 'waxberry'] fruits += ['pitaya', 'pear', 'mango'] print(fruits) # 列表切片 fruits2 = fruits[1:4] print(fruits2) # apple strawberry waxberry # 能夠經過完整切片操做來複制列表 fruits3 = fruits[:] print(fruits3) # ['grape', 'apple', 'strawberry', 'waxberry', 'pitaya', 'pear', 'mango'] fruits4 = fruits[-3:-1] print(fruits4) # ['pitaya', 'pear'] # 能夠經過反向切片操做來得到倒轉後的列表的拷貝 fruits5 = fruits[::-1] print(fruits5) # ['mango', 'pear', 'pitaya', 'waxberry', 'strawberry', 'apple', 'grape']
list1 = ['orange', 'apple', 'zoo', 'internationalization', 'blueberry'] list2 = sorted(list1) #按正序 # sorted函數返回列表排序後的拷貝不會修改傳入的列表 # 函數的設計就應該像sorted函數同樣儘量不產生反作用 list3 = sorted(list1, reverse=True) #按降序 # 經過key關鍵字參數指定根據字符串長度進行排序而不是默認的字母表順序 list4 = sorted(list1, key=len) print(list1) print(list2) print(list3) print(list4) # 給列表對象發出排序消息直接在列表對象上進行排序 list1.sort(reverse=True) print(list1)
咱們還可使用列表的生成式語法來建立列表,代碼以下所示。
import sys f = [x for x in range(1, 10)] print(f) f = [x + y for x in 'ABCDE' for y in '1234567'] print(f) # 用列表的生成表達式語法建立列表容器 # 用這種語法建立列表以後元素已經準備就緒因此須要耗費較多的內存空間 f = [x ** 2 for x in range(1, 1000)] print(sys.getsizeof(f)) # 查看對象佔用內存的字節數 print(f) # 請注意下面的代碼建立的不是一個列表而是一個生成器對象 # 經過生成器能夠獲取到數據但它不佔用額外的空間存儲數據 # 每次須要數據的時候就經過內部的運算獲得數據(須要花費額外的時間) f = (x ** 2 for x in range(1, 1000)) print(sys.getsizeof(f)) # 相比生成式生成器不佔用存儲數據的空間 print(f) for val in f: print(val)
除了上面提到的生成器語法,Python中還有另一種定義生成器的方式,就是經過yield關鍵字將一個普通函數改形成生成器函數。下面的代碼演示瞭如何實現一個生成斐波拉切數列的生成器。所謂斐波拉切數列能夠經過下面遞歸的方法來進行定義:
def fib(n): a, b = 0, 1 for _ in range(n): a, b = b, a + b yield a def main(): for val in fib(20): print(val) if __name__ == '__main__': main()
Python中的元組與列表相似也是一種容器數據類型,能夠用一個變量(對象)來存儲多個數據,不一樣之處在於元組的元素不能修改,在前面的代碼中咱們已經不止一次使用過元組了。顧名思義,咱們把多個元素組合到一塊兒就造成了一個元組,因此它和列表同樣能夠保存多條數據。下面的代碼演示瞭如何定義和使用元組。
# 定義元組 t = ('along', 66, True, '北京') print(t) # 獲取元組中的元素 print(t[0]) print(t[3]) # 遍歷元組中的值 for member in t: print(member) # 從新給元組賦值 # t[0] = '王大錘' # TypeError # 變量t從新引用了新的元組原來的元組將被垃圾回收 t = ('小黑', 20, True, '河南') print(t) # 將元組轉換成列表 person = list(t) print(person) # 列表是能夠修改它的元素的 person[0] = '小紅' person[1] = 25 print(person) # 將列表轉換成元組 fruits_list = ['apple', 'banana', 'orange'] fruits_tuple = tuple(fruits_list) print(fruits_tuple)
這裏有一個很是值得探討的問題,咱們已經有了列表這種數據結構,爲何還須要元組這樣的類型呢?
Python中的集合跟數學上的集合是一致的,不容許有重複元素,並且能夠進行交集、並集、差集等運算。
01-能夠按照下面代碼所示的方式來建立和使用集合
# 建立集合的字面量語法 set1 = {1, 2, 3, 3, 3, 2} print(set1) print('Length =', len(set1)) # 建立集合的構造器語法(面向對象部分會進行詳細講解) set2 = set(range(1, 10)) set3 = set((1, 2, 3, 3, 2, 1)) print(set2, set3) # 建立集合的推導式語法(推導式也能夠用於推導集合) set4 = {num for num in range(1, 100) if num % 3 == 0 or num % 5 == 0} print(set4)
02-向集合添加元素和從集合刪除元素
set1.add(4) set1.add(5) set2.update([11, 12]) set2.discard(5) if 4 in set2: set2.remove(4) print(set1, set2) print(set3.pop()) print(set3)
03-集合的成員、交集、並集、差集等運算
print(set1 & set2) # print(set1.intersection(set2)) print(set1 | set2) # print(set1.union(set2)) print(set1 - set2) # print(set1.difference(set2)) print(set1 ^ set2) # print(set1.symmetric_difference(set2)) # 判斷子集和超集 print(set2 <= set1) # print(set2.issubset(set1)) print(set3 <= set1) # print(set3.issubset(set1)) print(set1 >= set2) # print(set1.issuperset(set2)) print(set1 >= set3) # print(set1.issuperset(set3))
說明: Python中容許經過一些特殊的方法來爲某種類型或數據結構自定義運算符(後面的章節中會講到),上面的代碼中咱們對集合進行運算的時候能夠調用集合對象的方法,也能夠直接使用對應的運算符,例如&運算符跟intersection方法的做用就是同樣的,可是使用運算符讓代碼更加直觀。
字典是另外一種可變容器模型,Python中的字典跟咱們生活中使用的字典是同樣同樣的,它能夠存儲任意類型對象,與列表、集合不一樣的是,字典的每一個元素都是由一個鍵和一個值組成的「鍵值對」,鍵和值經過冒號分開。下面的代碼演示瞭如何定義和使用字典。
# 建立字典的字面量語法 scores = {'along': 95, '白元芳': 78, '狄仁傑': 82} print(scores) # 建立字典的構造器語法 items1 = dict(one=1, two=2, three=3, four=4) # 經過zip函數將兩個序列壓成字典 items2 = dict(zip(['a', 'b', 'c'], '123')) # 建立字典的推導式語法 items3 = {num: num ** 2 for num in range(1, 10)} print(items1, items2, items3) # 經過鍵能夠獲取字典中對應的值 print(scores['along']) print(scores['狄仁傑']) # 對字典中全部鍵值對進行遍歷 for key in scores: print(f'{key}: {scores[key]}') # 更新字典中的元素 scores['白元芳'] = 65 scores['諸葛王朗'] = 71 scores.update(冷麪=67, 方啓鶴=85) print(scores) if '武則天' in scores: print(scores['武則天']) print(scores.get('武則天')) # get方法也是經過鍵獲取對應的值可是能夠設置默認值 print(scores.get('武則天', 60)) # 刪除字典中的元素 print(scores.popitem()) print(scores.popitem()) print(scores.pop('along', 100)) # 清空字典 scores.clear() print(scores)
參考答案:
import os import time def main(): content = '北京歡迎你爲你開天闢地…………' while True: # 清理屏幕上的輸出 os.system('cls') # os.system('clear') print(content) # 休眠200毫秒 time.sleep(0.2) content = content[1:] + content[0] if __name__ == '__main__': main()
參考答案:
import random def generate_code(code_len = 4): """ 生成指定長度的驗證碼 :param code_len: 驗證碼的長度(默認4個字符) :return: 由大小寫英文字母和數字構成的隨機驗證碼 """ all_chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' last_pos = len(all_chars) - 1 code = '' for _ in range(code_len): index = random.randint(0, last_pos) code += all_chars[index] # print(code) return code print(generate_code(10))
參考答案:
def get_suffix(filename, has_dot=False): """ 獲取文件名的後綴名 :param filename: 文件名 :param has_dot: 返回的後綴名是否須要帶點 :return: 文件的後綴名 """ pos = filename.rfind('.') if 0 < pos < len(filename) - 1: index = pos if has_dot else pos + 1 return filename[index:] else: return '' print(get_suffix('along.txt')) print(get_suffix('along'))
參考答案:
def max2(x): m1, m2 = (x[0], x[1]) if x[0] > x[1] else (x[1], x[0]) for index in range(2, len(x)): if x[index] > m1: m2 = m1 m1 = x[index] elif x[index] > m2: m2 = x[index] return m1, m2 print(max2(x=[1,354,32,6,432]))
參考答案:
def is_leap_year(year): """ 判斷指定的年份是否是閏年 :param year: 年份 :return: 閏年返回True平年返回False """ return year % 4 == 0 and year % 100 != 0 or year % 400 == 0 def which_day(year, month, date): """ 計算傳入的日期是這一年的第幾天 :param year: 年 :param month: 月 :param date: 日 :return: 第幾天 """ days_of_month = [ [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] ][is_leap_year(year)] total = 0 for index in range(month - 1): total += days_of_month[index] return total + date def main(): print(which_day(1949, 10, 1)) print(which_day(1996, 7, 12)) print(which_day(2019, 1, 1)) if __name__ == '__main__': main()
參考答案:
def main(): num = int(input('Number of rows: ')) yh = [[]] * num for row in range(len(yh)): yh[row] = [None] * (row + 1) for col in range(len(yh[row])): if col == 0 or col == row: yh[row][col] = 1 else: yh[row][col] = yh[row - 1][col] + yh[row - 1][col - 1] print(yh[row][col], end='\t') print() if __name__ == '__main__': main()
from random import randrange, randint, sample def display(balls): """ 輸出列表中的雙色球號碼 """ for index, ball in enumerate(balls): if index == len(balls) - 1: print('|', end=' ') print('%02d' % ball, end=' ') print() def random_select(): """ 隨機選擇一組號碼 """ red_balls = [x for x in range(1, 34)] selected_balls = [] selected_balls = sample(red_balls, 6) selected_balls.sort() selected_balls.append(randint(1, 16)) return selected_balls def main(): n = int(input('機選幾注: ')) for _ in range(n): display(random_select()) if __name__ == '__main__': main()
說明: 上面使用random模塊的sample函數來實現從列表中選擇不重複的n個元素。
""" 《幸運的基督徒》 有15個基督徒和15個非基督徒在海上遇險,爲了能讓一部分人活下來 不得不將其中15我的扔到海里面去,有我的想了個辦法就是你們圍成一個圈 由某我的開始從1報數,報到9的人就扔到海里面 他後面的人接着從1開始報數,報到9的人繼續扔到海里面 直到扔掉15我的。因爲上帝的保佑,15個基督徒都倖免於難 問這些人最開始是怎麼站的,哪些位置是基督徒哪些位置是非基督徒。 """ def main(): persons = [True] * 30 counter, index, number = 0, 0, 0 while counter < 15: if persons[index]: number += 1 if number == 9: persons[index] = False counter += 1 number = 0 index += 1 index %= 30 for person in persons: print('基' if person else '非', end='') if __name__ == '__main__': main()