Python学习笔记(2)--《think Python》

C12. 元组

元组基本使用

元组是不可变序列,由()括住 (括号不是必要的) ,列表用 [ ] 括住,字典用 { } 括住。
其中元组和列表是序列,是有序的,可以用切片的形式访问元素。
创建只有一个元素的元组时,为了避免歧义需要添加“,”

>>> t = ('i')
>>> type(t)  # 这是一个str
>>> t = ('t',)
>>> type(t)  # 这是一个tuple

元组赋值

元组可以用来方便地用来交换两个变量以及多重赋值

>>> a, b = b, a  # 交换变量
>>> a, b, c = 1, 2, 3  # 多重赋值,左边是元组,右边是元组
>>> addr = '[email protected]'
>>> uname, domain = addr.split('@')  # 多重赋值,左边是元组,右边是列表

变长参数元组

函数可以读取一个变长的参数,一个以 * 开头的参数将参数聚集为一个元组
同时*也可将一个序列散布成多个参数传入函数

>>> def printall(*args):
... 	print(type(args))  # 是一个包含所有输入参数的tuple
...
>>> printall(1,3,4)
<class 'tuple'>
>>>
>>> def add(a, b):
... 	return a + b
...
>>> t = [1, 3]
>>> add(*t)
4
>>> t = (1, 3)
>>> add(*t)
4

元组和列表

zip 是一个内建函数,参数为两个或两个以上的序列,并将它们“拉链”成一个元组的列
表,每个元组包含每个序列中的一个元素

>>> s = 'abc'
>>> t = [0, 1, 2]
>>> zip(s, t)
[('a', 0), ('b', 1), ('c', 2)]

如果序列的长度不同,结果的长度和较短的序列相同。

>>> zip('Anne', 'Elk')
[('A', 'E'), ('n', 'l'), ('n', 'k')]

如果你结合 zip,for 和元组赋值,你得到一个同时遍历两个(或多个)序列的常用写法

def has_match(t1, t2):
	for x, y in zip(t1, t2):
		if x == y:
			return True
	return False

如果你要遍历一个序列中的元素和它们的下标,你可以使用内建函数 enumerate:

print(list(enumerate('abc')))  # [(0, 'a'), (1, 'b'), (2, 'c')]
# 相当于(index, element) in list(enumerate('abc'))
for index, element in enumerate('abc'):
	print(index, element)

元组和字典

字典有个方法称为 items,返回一个元组的列表,每个元组是键 - 值对。

>>> d = {'a':0, 'b':1, 'c':2}
>>> t = d.items()
>>> print t
[('a', 0), ('c', 2), ('b', 1)]

结合 items,元组赋值和 for 循环,你可以得到遍历字典的键 -值对的常用写法:

for key, val in d.items():
	print(val, key)

练习

Exercise 12.4 更多关于回文的练习!

  1. 编写函数,从文件中读取一个单词表,打印所有回文的单词。
    下面的例子给出可能的输出结果:
    [‘deltas’, ‘desalt’, ‘lasted’, ‘salted’, ‘slated’, ‘staled’]
    [‘retainers’, ‘ternaries’]
    [‘generating’, ‘greatening’]
    [‘resmelts’, ‘smelters’, ‘termless’]
    提示:你也许需要构建一个字典满足从字母的集合到这些字母可以组成的单词列表的
    映射。问题是你如何表示这个字母集合使得它们可以作为字典的键?
  2. 修改之前的程序,使程序按照结果集合的大小从大到小输出。
  3. 在拼字游戏中,如果你手头的 7 个字母和桌面上的 1 个字母组成一个 8 个字母的单词,
    你实现了“bingo” 。哪 8 个字母组成的集合有最大的概率实现“bingo” ?提示:有 7
def readWordsAppend():
    t = []

    fin = open("words.txt")
    for line in fin:
        word = line.strip()
        t.append(word)

    return t

def getAnagramList(t, n):
    d = dict()
    for word in t:
        wordList = list(word)
        wordList.sort()
        key = ''.join(wordList)
        tem = d.get(key, [])
        tem.append(word)
        d[key] = tem

    t = []
    for wordList in d.values():
        if(len(wordList[0]) == n):
            t.append((len(wordList), wordList))
    t.sort(reverse=True)

    return t

if __name__ == '__main__':
    num = 0
    for n, w in getAnagramList(readWordsAppend(), 8):
        if(n >= num):
            num = n
            print(w)

Exercise 12.5 下面是另一个 Car Talk 难题:
如果每次你从一个单词中删除一个字母它仍是一个有效的英语单词,在英语中满足这样条件的最长的单词是什么?删除的字母可以位于两端或者中间,但是你不能重新排列字母。每次你删除一个字母,你得到另一个英语单词。最终你得到一个只有一个字母的单词。我要知道最长的单词是什么,它有多少字母?我要给出一个例子:Sprite。你从 sprite 开始删除字母,首先删除 r,我们得到单词 spite,接着删除 e,我们得到 spit,再删除 s,我们得到 pit,it 和 I。
编写程序,找出可以按这中方法缩小的所有单词,并找出最长的一个。这个练习比以往的都更有挑战性,所以给出一些建议:

  1. 你也许需要编写一个函数,参数为一个单词,函数找出所有删除一个字母后仍合法的
    单词,即原单词的“孩子” 。
  2. 递归的看,一个单词是可缩小的,如果它所有的孩子都是可缩小的。作为基本状态,
    你可以认为空字符串是可以缩小的。
  3. 我提供的单词表 words.txt 中不包括单字母的单词。所以你需要添加“I” , “a”和空
    字符串。
  4. 为了提高你的程序的效率,你需要记住已知的可缩小的单词
def readWordsSet():
    s = set()

    fin = open("words.txt")
    for line in fin:
        word = line.strip()
        s.add(word)
    s.add('I')
    s.add('i')
    s.add('a')
    s.add('')
    return s

def checkIsScale():
    for word in wordSet:
        isScale(word)

def isScale(word):
    if word in wordDict:
        return wordDict[word]
    t = getWordChild(word)
    for childWord in t:
        if(isScale(childWord)):
            trueWordList.append((len(word), word))
            wordDict[word] = True
            return True
    wordDict[word] = False
    return False

def getWordChild(word):
    t = []
    wL = list(word)
    for index in range(len(word)):
        wTem = ''.join(wL[:index] + wL[index+1:])
        if(wTem in wordSet):
            t.append(wTem)
    return t

def printChildWord(word):
    print(word)
    for i in range(len(word)):
        for childW in getWordChild(word):
            if wordDict[childW]:
                print(childW)
                word = childW
                continue

if __name__ == '__main__':
    wordSet = readWordsSet()
    wordDict = {'':True}
    trueWordList = []
    checkIsScale()
    trueWordList.sort(reverse=True)
    longScaleWord = trueWordList[0]
    printChildWord(longScaleWord[1])

猜你喜欢

转载自blog.csdn.net/LeonShaw_zh/article/details/83020420