列表部分习题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chivalrousli/article/details/38842867

练习10-6

编写一个函数 is_sorted,接收一个列表作为形参,并当列表是按照升序排好序的时候返回True,否则返回False。你可以假定(作为前置条件)列表的元素是可以使用关系操作符<,>等比较的。

例如,is_sorted([1,2,2])应当返回True,而is_sorted(['b',''a])应当返回False.

def is_sorted(t):
    for i in range(len(t)-1):
        if t[i]>t[i+1]:
            return False
    return True

print is_sorted([1,2,2])
print is_sorted(['b','a'])</span>

练习 10-7 

两个单词,如果重新排列其中一个的字母可以得到另一个,它们互为回文(anagram)。编写一个函数 is_anagram,接收两个字符串,当它们互为回文时返回True.

def is_anagram(string1,string2):
    if len(string1) != len(string2):
        return False
    for letter in string1:
        if letter not in string2:
            return False
    for letter in string2:
        if letter not in string1:
            return False
    return True

print is_anagram('string','ginrts')
print is_anagram('string','strngi')
print is_anagram('string','strinr')
print is_anagram('string','strin')
</span>


练习10-8

(所谓的)生日悖论:

1.编写一个函数has_duplicates接收一个列表,当其中任何一个元素出现多于一次时返回True。它不应当修改原始列表。

def has_duplicates(t):
    s = t[:]
    s.sort()
    for i in range(len(s)-1):
        if s[i] == s[i+1]:
            return True
    return False

print has_duplicates(['a','b','c','b'])
print has_duplicates(['a','b','c','d'])</span>
2.如果你的班级中有23个学生,那么其中有两人生日相同的几率有多大?你可以通过随机生成23个生日的样本并检查是否有相同的匹配来估计这个几率。提示:可以使用random模块的randint函数来生成随机生日。

import random

def has_duplicates(t):
    s = t[:]
    s.sort()
    for i in range(len(s)-1):
        if s[i]== s[i+1]:
            return True
    return False

def randomDays(n):
    t = []
    for i in range(n):
        day = random.randint(1,365)
        t.append(day)
    return t

def count_match(students,samples):
    count_equal = 0
    for i in range(samples):
        t = randomDays(students)
        if has_duplicates(t):
            count_equal += 1
    return count_equal

num_students = 23
num_simulations = 1000
count = count_match(num_students,num_simulations)

print 'After %d simulations' % num_simulations
print 'with %d students' % num_students
print 'there were %d simulations with at least one match'% count

运行结果为:

After 1000 simulations
with 23 students
there were 492 simulations with at least one match

即为若班级学生有23位,那么其中有两人生日相同的几率超过50%.

练习 10-9 

编写一个函数 remove_duplicates,接收一个列表,并返回一个新列表,其中只包含原始列表的每个元素的唯一一份。

def remove_duplicates(t):
    s = t[:]
    s.sort()
    i = 0
    while i <len(s)-1:
        if s[i] == s[i+1]:
            del s[i+1]
            i = i - 1
        i = i + 1
    return s

list1 = [0,1,1,1,2,2,3,3]
print 'original lise is ',
print list1
print 'After remove is ',
print remove_duplicates(list1)
运行结果为:

original lise is  [0, 1, 1, 1, 2, 2, 3, 3]
After remove is  [0, 1, 2, 3]

练习 10-10  编写一个函数,读取文件 words.txt,并构建一个列表,每个元素是一个单词。给这个函数编写两个版本,其中一个使用append方法,另一个使用  t = t+[x]的用法。哪一个运行时间更长,为什么?

import time

def append_me():
    t = []
    fin = open("words.txt")
    for line in fin:
        word = line.strip()
        t.append(word)
    return t

def listplus():
    t = []
    fin = open("words.txt")
    for line in fin:
        word = line.strip()
        t = t + [word]
    return t

start1 = time.time()
t1 = append_me()
end1 = time.time()
time1 = end1 - start1
print "use append method ,the time is ",time1,"seconds"

start2 = time.time()
t2 = listplus()
end2 = time.time()
time2 =end2 - start2
print "use list plus method,the time is",time2,"seconds"

运行结果为:

use append method ,the time is  0.106966018677 seconds
use list plus method,the time is 45.1239600182 seconds

可见列表直接相加的方法消耗时间远远超过直接使用append方法。

练习 10-11

要检查一个单词是否出现在单词列表中,可以使用in操作符,但由于它需要按顺序搜素所有单词,可能会比较慢。

因为单词是按照字母顺序排列的,我们可以使用二分查找来加快速度。二分查找的过程类似于在字典中查找单词。你从中间开始,检查需要找的单词是不是在列表中间出现的单词之前。如果是,则继续用同样的方法搜索前半部分。否则,搜索后半部分。

不论何种情况,都将搜索空间减少了一半。如果单词列表有113,809个单词,那么大概会耗费17步来找到单词,或者确定它不在列表中。

编写一个函数bisect,接收一个排好序的列表,以及一个目标值,当目标值在列表中,返回其下标,否则返回None。

def append_me():
    t = []
    fin = open("words.txt")
    for line in fin:
        word = line.strip()
        t.append(word)
    return t

def bisect(t,word):
    start_index = 0
    end_index = len(t)-1
    while start_index <= end_index:
        middle = (start_index + end_index) / 2
        if word == t[middle]:
            return middle
        elif word < t[middle]:
            end_index = middle - 1
        else:
            start_index = middle + 1
    return None

list1 = append_me()
index = bisect(list1,'genets')
print index
print list1[index]
index2 = bisect(list1,'aa')
print index2
print list1[index2]
index2 = bisect(list1,'zymurgy')
print index2
print list1[index2]
运行结果:

40523
genets
0
aa
113808
zymurgy

包括首尾和中间任一元素均可返回正确结果。

练习 10-12

两个单词,如果其中一个是另一个的反向序列,则称它们为“反向对”。编写一个程序找到单词表中出现的全部反向对。

此处先将练习10-11的代码稍作修改,命名为 binary_search.py。

代码如下:

def append_me():
    t = []
    fin = open("words.txt")
    for line in fin:
        word = line.strip()
        t.append(word)
    return t

def bisect(t,word):
    start_index = 0
    end_index = len(t)-1
    while start_index <= end_index:
        middle = (start_index + end_index) / 2
        if word == t[middle]:
            return True
        elif word < t[middle]:
            end_index = middle - 1
        else:
            start_index = middle + 1
    return False

if __name__ == '__main__':
    list1 = append_me()
在代码reverse_pair.py中引用binary_search.py



from binary_search import *

def reverse_pair(list1,word):
    rev_word = word[::-1]
    return bisect(list1,rev_word)

if __name__ == '__main__':
    list1 = append_me()

    for word in list1:
        if reverse_pair(list1,word):
            print word,word[::-1]

运行结果的一部分为:

wop pow
wort trow
worts strow
wos sow
wot tow
wots stow
wow wow
xis six
ya ay
yah hay
yak kay
yam may
yap pay
yaps spay
yar ray
yard dray
yaw way
yaws sway
yay yay
yeh hey

练习 10-13

两个单词,如果从每个单词中交错取出一个字母可以组成一个新的单词,我们称它们为“互锁”(interlocking)。例如,"shoe"和"cold"可以互锁组成单词"schooled"。

1 编写一个程序找到所有互锁的词。提示:不要穷举所有的词对。

2 能不能找到“三互锁”的单词?也就是,从第一,第二或者第三个字母开始,每第三个字母合起来可以形成一个单词。

还是基于将互锁形成的单词切片。

from binary_search import *

def interlock(list1, word):
    evens = word[::2]
    odds = word[1::2]
    return bisect(list1, evens) and bisect(list1, odds)


def interlock_general(word_list, word, n=3):
    for i in range(n):
        inter = word[i::n]
        if not bisect(word_list, inter):
            return False
    return True


if __name__ == '__main__':
    list1 = append_me()

    for word in list1:
        if interlock(list1, word):
            print word, word[::2], word[1::2]

#    for word in word_list:
#        if interlock_general(word_list, word, 3):
#            print word, word[0::3], word[1::3], word[2::3]


运行的部分结果如下:

wooded woe odd
woods wos od
woof wo of
woofs wos of
wooled woe old
woops wos op
woos wo os
wordy wry od
wormy wry om
worry wry or
wound wud on
wounds wud ons
wreath wet rah
wreaths wets rah
wries wis re
wriest wis ret
yaird yid ar
yairds yid ars
yeah ya eh
yean ya en
year ya er
yeas ya es
yuan ya un


展开阅读全文

没有更多推荐了,返回首页