元组是不可变序列,由()括住 (括号不是必要的) ,列表用 [ ] 括住,字典用 { } 括住。
其中元组和列表是序列,是有序的,可以用切片的形式访问元素。
创建只有一个元素的元组时,为了避免歧义需要添加“,”
>>> 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 更多关于回文的练习!
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。
编写程序,找出可以按这中方法缩小的所有单词,并找出最长的一个。这个练习比以往的都更有挑战性,所以给出一些建议:
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])