2020-04
23

记忆中的万松园市场

By xrspook @ 11:49:41 归类于: 烂日记

在我记忆之中,我从来没有把一本编程类的书完整看完过,以前我都是挑着来看。自己需要用哪些功能,就去找哪些章节去看,而这次学习python,我是下了狠心的。几乎可以这么说,一天到晚我的脑子里就只有那些东西,即便是睡着了也一样。做梦的时候,我依然是想着python。还记得在学习递归的时候,某天晚上我做梦梦见了一个瀑布,但实际上瀑布并不是真的瀑布,那不过是一个正在流着很多水的建筑物外墙。那个瀑布从一个分成两个,再分成多个。不同的水量有不同的效果。我第一个感觉是那应该是一个自然形成的瀑布吧。但当水全部停住的以后我才发现,原来一切都是人造的。瀑布是在一个玻璃屋的外墙上形成的。之所以有这个脑洞,大概是因为我的记忆深处借鉴了东站广场的那个瀑布。还记得初中的时候我们几个同学还专门过去那里看人造瀑布。后来我不记得那里变成怎样了。反正那应该是东方宝泰外面的吧。再到后来,去东站附近通常都只是为了去宜家家私,然后下到东方宝泰里面的吉之岛,其它的东西一点印象都没有了。至于从前的那个瀑布还有没有,我实在想不起来。自从宜家家私再也不在东站的那个卖场以后,感觉我好久都没有去过那个地方了。光是东方宝泰一家,对我和我妈都没有什么吸引力。

城市的变迁,总免不了会发生东西不断消亡,但当从前熟悉的东西消失,会让人觉得无比怀念、依依不舍,但即便这样,它们还是会消失,除了在从前的照片和影像资料里再次重温,无论如何我们都回不到那个时候了。

有时我会很怀念从前到万松园市场。万松园市场在我的脑子里印象非常深刻,那些卖鱼的、卖菜的,还有卖杂货的,我都记忆犹新。我甚至还记得了当年不同品种货物的布局。虽然有些小店在我印象之中已经很模糊了,但是我还非常记得,卖鱼的在哪里,卖烧腊的在哪里。那个卖烧腊对出的通道上,某年过节,有人在那里卖老鼠肉。虽然我根本不记得卖的老鼠肉是什么样的,我甚至没有见过一眼,但是从叫卖声让我知道,有人在路中央卖老鼠肉。万松园市场对我来说是一个神奇的地方,虽然跟沙园市场比起来,那个地方不大。那条叫做万松路的路永远都是熙熙攘攘,我甚至记不起汽车是怎么在那条路上行驶的,因为上面总是挤满人。不是每个市场都会让一整条马路不复存在。那里对我来说就是最早的步行街。从前的万松园市场,或者不是这样的,或许我只记住了它热闹的一面。很久以前,这个市场进行了改造,全部都档口都入室经营。我一直觉得,新的万松园市场我很陌生。不只是我,我的家人也很少再去那里买菜了。之所以这样,其中一个很重要的原因是他们把蔬菜和水果档口放到了二楼,对老人来说,这非常不方便,因为没有电梯。我甚至一点都记不起2楼到底是怎么布局的。过去十几二十年我加起来,估计上去5次都不到。

在南丰商场下车,穿过人挤人的万松园市场,再过一条马路,山货铺的上面就是外婆的家了。

2020-04
22

字典还能这样玩!

By xrspook @ 18:30:55 归类于: 扮IT

一开始,我自己写的脚本能运行,但慢到怀疑人生。吃了个饭,折腾了半个小时后,字母表才处理到b而已,显然这是个失败的操作。我的做法是常规地为词汇表建立字典,然后历遍字典里的每个单词,单词进入函数后跟字典的另一个单词比较,比较方法是把单词(即字符串)打散为字符列表然后排列,如果排列一致,且被比较的单词小于拿去比的单词,它们就是一伙的,贴在被比较的单词列表下。列表长度大于2就返回列表然后打印。这样是可以选出异构词的,但非常非常慢!

看过参考答案之后我跳起来了,他们用了一句”.join(lists),这等于是把列表str重新粘成一个字符串,我那个去!他们把单词用列表打散重排再粘回去,最关键的是,这个唯一的重排字符串他们在建立字典的时候就作为key,所有与之有一样字符的全部被看作小弟被放置这个键的键值里。字典还是字典,但字典的键成了规则字符串,键值则是排列组合过的词汇表。我根本没想到啊,怎么可能想得到呢!!!!!

题目要求倒序打印,然后要求找出能组成最多异构词的8个字母。但实际上参考答案的输出问非所答,比如没有倒序,比如只是把8个字母的异构词摆出来,没确切告诉你最多的是什么。

Exercise 2: More anagrams! Write a program that reads a word list from a file (see Section 9.1) and prints all the sets of words that are anagrams. Here is an example of what the output might look like:
[‘deltas’, ‘desalt’, ‘lasted’, ‘salted’, ‘slated’, ‘staled’]
[‘retainers’, ‘ternaries’]
[‘generating’, ‘greatening’]
[‘resmelts’, ‘smelters’, ‘termless’]
Hint: you might want to build a dictionary that maps from a collection of letters to a list of words that can be spelled with those letters. The question is, how can you represent the collection of letters in a way that can be used as a key? Modify the previous program so that it prints the longest list of anagrams first, followed by the second longest, and so on. In Scrabble a “bingo” is when you play all seven tiles in your rack, along with a letter on the board, to form an eight-letter word. What collection of 8 letters forms the most possible bingos? Solution: http://thinkpython2.com/code/anagram_sets.py.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
from time import time
def sorted_anagram(d):
    l = []
    for key in d:
        if len(d[key]) > 1:
            l.append((len(d[key]), d[key])) # 这是个由列表创建的元组?
    return sorted(l, reverse = True) # 倒序神马真折腾
def eight_letters(d, num):
    global length # 全局变量都用上了,就为了记录个最大值
    new_l = []
    for key in d:
        if len(key) == num and len(d[key]) > 1:
           new_l.append((len(d[key]), d[key]))
           if len(d[key]) >= length:
               length = len(d[key])
    return sorted(new_l)
def sorted_letters(word):
    list_word = sorted(list(word)) # 先把字符串打散为字符列表,然后排序
    reword =''.join(list_word) # 再把字符列表回粘成字符串
    return reword
def set_dict(fin):
    d = {}
    for line in fin:
        word = line.strip()
        reword = sorted_letters(word) # 打散重排相当关键,必须在建立字典时就做!!!
        if reword not in d:
            d[reword] = [word] # 字典的键已经不是单词,是纯粹的规律字符串
        else:
            d[reword].append(word) # 字典的键值才是词汇表里的单词
    return d
fin = open('words.txt')
length = 0
count = 0
start = time()
d = set_dict(fin)
for item in sorted_anagram(d):
    print(item)
    count += 1
print(count)
for item in eight_letters(d, 8):
    if item[0] == length:
        print(item)
end = time()
print(end - start)
# ......
# (2, ['abacas', 'casaba'])
# (2, ['aba', 'baa'])
# (2, ['aals', 'alas'])
# (2, ['aal', 'ala'])
# (2, ['aahed', 'ahead'])
# (2, ['aah', 'aha'])
# 10157 # 全体异构词
# (7, ['angriest', 'astringe', 'ganister', 'gantries', 'granites', 'ingrates', 'rangiest'])
# 异构词最多的8字母单词(共7个异构词)
# 0.6079998016357422
2020-04
22

字典转元组

By xrspook @ 13:15:37 归类于: 扮IT

不搞复杂的,不用超纲的方法做感觉上很简单的事其实不简单。搞明白这个练习后,列表、字典、元组的相爱相杀我算是有点明白了。感谢那个我觉得过于复杂的参考答案,逼我折腾出了我自己的版本。

开心!居然习题1就用上了zip这个这章书最后才提到的大招。字典的键值对互换变得如此简单,我的脑洞又开大了。

Exercise 1: Write a function called most_frequent that takes a string and prints the letters in decreasing order of frequency. Find text samples from several different languages and see how letter frequency varies between languages. Compare your results with the tables at http://en.wikipedia.org/wiki/Letter_frequencies. Solution: http://thinkpython2.com/code/most_frequent.py.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
def most_frequent(sth):
    d = {}
    for letter in sth: # 字符串转为字符映射到频率的字典
        d[letter.lower()] = d.get(letter.lower(), 0) + 1 # 大写的你给我降为小写
    t = tuple(zip(d.values(), d.keys())) # 用zip互换字典的键和键值,生成元组(也可以生成列表,但生成新字典你会哭死)
    return sorted(t, reverse = True) # 以第一元素降序输出
sth = 'This chapter presents one more built-in type, the tuple, and then shows how lists, dictionaries, and tuples work together. I also present a useful feature for variable-length argument lists, the gather and scatter operators.'
t = most_frequent(sth)
for item in t:
    print(item) # 原汁原味输出元组好,因为空格不用''圈着都不知道那里有东西
# (33, ' ')
# (25, 'e')
# (23, 't')
# (16, 's')
# (15, 'r')
# (14, 'a')
# (11, 'o')
# (11, 'n')
# (10, 'i')
# (10, 'h')
# (9, 'l')
# (7, 'u')
# (7, 'p')
# (5, ',')
# (4, 'g')
# (4, 'd')
# (3, 'w')
# (3, 'f')
# (3, 'c')
# (2, 'm')
# (2, 'b')
# (2, '.')
# (2, '-')
# (1, 'y')
# (1, 'v')
# (1, 'k')
2020-04
22

写得过于简单了吧

By xrspook @ 9:29:12 归类于: 烂日记

我看的那个中文版Think Python 2的第11章,习题几乎可以这么说,没一道题的相关是做对的。有些东西,习题跟现在的Think Python 2英文版不一样,我觉得可能是英文版修正了某些东西。修正完以后,英文版并没有写什么更新说明之类的东西,但即便有,中文版翻译的人翻译完以后大概也不会时刻关注英文版有没有变动。同一道题的关联引用,这种东西怎么可以凭着感觉来呢?第一次遇到的时候,我云里雾里,因为按照中文版的那个说法,在某一章书的习题里根本找不到那个东西,但在我印象中,我的确是做过那些习题,到底是在哪一章书里的呢?另外一个版本的中文版那里的索引做对了。当我回看英文原版的时候,发现他们引用某个习题真的写得超简单,但是那些习题全部都是有超连接的,而且锚点到了某一章书的某个确切位置。所以我看的那个中文版之所以是现在这个样子,是不是因为他只是进行了文字上的翻译,还没有仔细研究那些超链接之类的东西呢?又或者在他翻译的时候,他并不是看着英文电子版,我是看英文纸质或者PDF等没有超链接之类的东西。电子版这种东西最让人觉得舒服的应该是哪怕你不标明是那是哪一章书的习题,你只是说那是习题几,只要你把超链接做上去,一切好办。

我看的那个中文版让我无语,但是英文原版也好不到哪里去。因为英文原版的作者脑洞实在太大,让人不知道如何言表。我觉得变成编程这东西,你得给出一个范围,然后再给出一个参考结果,才能让人有奔头。但是他只叫你这般测试,然后再给出一个参考的脚本。在不看脚本之前,如果我只是运行的脚本,而一开始的时候,我们设定的自定义参数不同,该如何判断读者自己的脚本写得对不对呢?有些参数他们完全可以先给出来,或者你会说,那岂不是成了一个提示。这又不是测验考试,重要的不是结果,而是如何整出那个结果,所以即便给你看到最终结果,你不懂过程,还是折腾不出来。英文原版的作者把那些条件参数写在他的脚本里面,而当你写自己的脚本的时候,你又清楚明白到你必须得设定那些参数,但是应该确定为什么呢?拿不准。这就会进入一个怪圈。首先是读者看着题目,自己解答,解答完以后测试,觉得没问题,打开参考答案运行,因为参数答案的结果跟读者得到的不一样,接着我们还得去仔细研究参考答案到底用了什么参数。然后把那个参数放在我们自己的脚本里再运行。对比两个运行的效果。这不是非常折腾吗?如果没有那个隐藏的参数,读者完全可以自己运行一遍,拿参考答案再运行一遍,对比结果就行了。我们最终要做到的不就是那个结果吗?当然,如果得出结果完全一致以后,还是建议大家再研究一下参考答案跟自己的脚本有什么区别,想一想这些区别会不会导致什么问题。

Think Python 2这本书,不只是习题参数设置很让人迷茫。在某些章节里,写得也不细致,比如说元组那一章。元组这个东西据说在其他编程语言里面是没有的。在介绍元组之前,已经说过字符串、列表以及字典。前面三个东西一个套一个,挺容易理解,但是加了元祖进去以后,世界就变得混沌了。因为列表字典元组这三个东西可以互相组合互相转化。有些可变,有些不可变。有些人可排序,有些无效。要真的说清楚元组,第12章书里面已经说到的东西以及已经举过的例子还不足以解决问题。如果他们不把所有东西都说一遍,起码他们得给我们一个列表。告诉我们这些东西可以控制元组,至于具体的使用方法,大家可以查手册。

或许当我把一整本书都看完以后,我的想法又不是我现在这个了。

2020-04
21

PK我自己

By xrspook @ 19:04:38 归类于: 扮IT

用了几分钟时间,写了个用字典法查找10万单词的词汇表回文词的脚本。字典法肯定要比列表二分法快,但到底快多少呢?实测大概10倍。相比之下,字典法语言实在简练太多。二分法的函数还得考虑递归和起点终点神马,字典法一个in杀到底。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# import time
# def in_bisect(library, first, last, myword): # 二分法搜索,10万数据查询最多只需不到20步
#     if first > last: # 这是一句拯救了我的条件
#         return -1
#     else:
#         mid = (first + last)//2
#         if myword == library[mid]:
#             return mid
#         elif library[mid] > myword:
#             return in_bisect(library, first, mid-1, myword)
#         else:
#             return in_bisect(library, mid+1, last, myword)
# j = 0
# count = 0
# library = []
# fin = open('words.txt')
# for line in fin:
#     word = line.strip()
#     library.append(word)
# library.sort()
# start = time.time()
# for i in range(len(library)-1): # 二分法搜索 
#     j = in_bisect(library, 0, len(library)-1, library[i][::-1])
#     if j > -1 and library[i] < library[j]:
#         print(library[i], library[j])
#         count += 1
# print(count)
# end = time.time()
# print(end - start)
# 397, 1.2810001373291016 # 二分法搜索
 
import time
def set_dict(fin): # 字典法搜索
    d = {}
    for line in fin:
        word = line.strip()
        d[word] = 0
    return d
count = 0
fin = open('words.txt')
start = time.time()
mydict = set_dict(fin)
for word in mydict:
    if word[::-1] in mydict and word < word[::-1]:
        print(word, word[::-1])
        count += 1
print(count)
end = time.time()
print(end - start)
# 397, 0.14300012588500977 # 字典法搜索
© 2004 - 2026 我的天 | Theme by xrspook | Power by WordPress