append,extend

众所周知,在学习python时,append()和extend()通常是算法菜鸟的眼中钉肉中刺,在期中期末考试时经常因为没法区分这两者的区别而坐在电脑前崩溃痛哭不知道自己活了这么多年在学什么。怎么回事?是因为你没学这一课。

append

动词,中文释义为:添加
但不为人知的是,append这个单词作“添加”时,强调以“附加内容”添加。
比如在信件的末尾append a note(添加一个注解)

append的名词形式,appendix,就自然而然变成了“附录”的意思,同样也有“阑尾”的意思,因为阑尾是人身体中一个可要可不要的、附加的内容。

extend

动词,中文释义为:扩展、延长
强调的是在事物原有的基础上将其进行拉伸扩大。
比如我向杨神伸出学习英语的友好的双手,就可以说I extend my hand to you.

另一种情形,我请了两天年假准备去新疆滑雪,结果我没玩爽,还想再请两天年假继续滑(我年假呢),就可以说I decide to extend my travel in Xinjiang. 我决定延长我在新疆的旅行(时长)

两者在英语和中文里的释义相似,所以append()和extend ()在python中功能也类似,但涉及到具体用法时,它们各自的功能其实与它们单词含义的内容是同步的、一致的。

比如append()方法就只能用于在列表末尾添加新的对象,作“附加”用;
而extend()方法就用于在列表末尾一次性追加另一个序列中的多个值,意思是用新列表“扩展”原有列表。

pop,remove

老程序员都知道了,pop()和remove()方法在处理列表时的区别是很明显的,入门的时候我们就学过:

  1. pop()是必须有一个返回值的,而remove()是不反回任何值的。
  2. pop()在没有输入参数的情况下也可以使用,而remove()没有输入参数时是会报错的。
  3. pop()使用元素的索引,而remove()使用元素的值。

可是为什么pop()和remove()同样都作“删除”使用,两个方法却隐含这么多不同?从英语单词的视角出发去研究pop和remove,你或许会有新的答案:

pop

动词,中文释义为:(使)砰地爆开,砰地脱落;迅速去,短暂逗留;突然出现,短暂出现;等等等等

你可以发现pop在作动词的时候它的释义跟中台很多单词一样,都是没完没了的,所以在记这一类意义宽泛的单词的时候,不应该去研究它的具体释义,而应该去调查它的“意象”。

在十五世纪中期的时候,pop就已经用来形容 -- 某个东西“啵”地一声爆开。
比如,the cork popped(开香槟开红酒时的木塞“啵”地一下爆开了)

在这个意象之上,又延伸出了另一个意象,某个东西“啵”地一下脱离了原位。
比如,the news made her eyes pop(这个让人惊讶的新闻让她眼睛爆了出来)

所以python里的pop()方法就取自上面这个意象,形容某个东西被取出、弹出了“原位”,所以pop()方法首先是基于【索引】来处理元素的,但东西被取出原位后又没有完全消失,所以是有一个【返回值】的。

remove

动词,中文释义为:拿走、挪走

remove这个单词是属于词根词缀法的入门单词,它由前缀re-和词根move组成,前缀re-表示“退回、离开”,而词根move表示移动,朝着退回、离开的方向移动,就表示拿走、挪走。

把一个东西拿走、挪走,本质上就意味着让它原来在时空中的存在消失。
比如,I removed my computer from the table. (我把桌上的电脑拿走了) 意思是桌上的电脑已经不在原来的位置了,我也不知道原来的桌上曾经是放着这个电脑的。

同样,remove还可以用于开除某个人的位置、删除某个文件:He was removed from the position.(他从职位上开除了)

所以python里的remove()方法就跟remove单词所象征的含义是一样的,把一个东西从时空角度取出,所以参照的是【值】,并且删除时不会返回值,因为已经拿走了、不存在了。

字符串的处理方式中,有哪些英语单词值得深究?

大小写: title / upper/lower (case)

string.title() - 每个单词首字母大写
string.upper() - 全字符大写
string.lower() - 全字符小写

老程序员当然对这几个代码再熟悉不过,可是你真的研究过为什么title的功能是首字母大写吗?你真的研究过为什么upper就是大写,lower就是小写吗?为什么要区分大写小写?这里面其实有非常深刻的社会历史文化变迁之知识,世界上所有语言都是这样。

大小写的历史沿革,就跟英语语言的发展史紧密相关:

古英语的手稿中,英语的拼写是不作大小写区分的。

中古英语的手稿中,词汇作大小写区分仅仅只是为了美观、分段,而不存在语法句法的规则。

在中古英语发展期间,印刷机被发明。那时候标点符号还没有被广泛普及,所以人们慢慢开始在句首、专有名词和一些需要作意义强化的动词和名词前大写,为了给句子作区隔、突出具体单词的意义。(聪明的程序员读到这里就会发现,代码里经常也会以“作区隔”为由,在代码中加入一个大写字母,如“firstNum”,“self.assertNotIn(item, list)”)

时间逐渐来到了近代英语时期,其间人们开始受到德语版式的影响,逐渐追求把所有名词的首字母都进行大写。如下图美国1787宪法原文:
Pasted image 20240424234721.png

这种大写方式随着更多英语版式规则的制定,逐渐在19世纪消散。人们在制定新的英语版式规则的时候最终才慢慢规定,只在标题突出动词和名词,正文只在句首和专有名词首字母大写

强化意义大写的规则有二:

而小写就是:

case

讲到这里又觉得奇怪了!跟不上了!怎么回事?我代码里明明只学了title/upper/lower,你这里的“case”是从哪来的?

case这个单词当然也跟历史文化有关了。

case的拉丁文词源,意思是把某个东西拿住、包裹着、支撑起来的意思,所以才有了如今其作名词词性的“盒子,包装”之意。

在16世纪印刷风靡全球之时,case的意思就被借用到印刷业里,专门用来指代印刷工人用来装活字印刷字母的木格子。观察下图你还可以观察到另外一个现象,因为小写字母用得比较多,所以lower case的格子也会大很多,可以放很多替换装。

参考图片:
Pasted image 20240424234626.png
Pasted image 20240424234640.png
参考视频:[https://www.youtube.com/watch?v=n4CEJe7H-44](https://www.youtube.com/watch?v=n4CEJe7H-44

upper (case) & lower (case)

讲完case之后,你马上就可以理解为什么upper case是大写,而lower case是小写了。

upper case,顾名思义,是在上面的盒子,而lower case,则是在下面的盒子。

当时的印刷工人为了印刷起来顺手、方便,所以通常把常用的小写字母放在下面的盒子里,而大写的字母放在上面的盒子里(可以再看一下上面的图片)。久而久之,就用upper case来指代所有大写字母,而lower case就用来指代所有小写字母。所以才有了我们代码中的string.upper()和string.lower()。

title (case)

title这个单词的词源和意义都非常简单:
小说/电影/电视剧/艺术/游戏的主题,叫title
文章的标题,叫title
教授、领导的称号,叫title
这样顺下来,你很容易就能发现,title是所有内容的大成、精华,可以把散的东西收束在一起。

结合上文的历史你就会发现,Title Case:首字母大写,其实就是为了突出title作为“所有内容的精华”的强调之意,所以才有了string.title() - 每个单词首字母大写的处理方式。

capital (caps)

老程序员如果读到这里就又会开始痛苦了,从小到大一直陪伴着我的那把键盘,键盘上那个孤立无援的“caps lock”,难道不也是大写的意思吗?怎么回事?为什么写代码的时候改变大小写只有title/upper/lower,却没有我键盘上锁定大小写的“caps lock”?

caps lock之所以叫caps lock,就是想表达“锁定大写”。lock是🔒,那么caps就是大写。caps是capital的截断词,为了省略字符就把长长的capital砍成了caps。

capital这个单词的词源同样来自拉丁语,原来的意思表示“跟头有关的”。所以作“大写”释义的时候,capital的意思要比upper case更窄一些。刚刚讲的upper case,木盒子里装的应该全部都是大写字母,而capital,其实主要是指单词的首字母,也就是单词的“头”,需要大写。

capital的动词,是加上-ize这个使动后缀拼出来的,capitalize。当我们说to capitalize a word,其实就是把某个单词的首字母变成大写,比如,polish -- Polish。并且capitalize的适用范围,一般只限定在一个单词里,而不是一个句子,更不是一个编程环境中的字符串了。

删除空白 strip

string.strip()
string.lstrip()
string.rstrip()
string.strip(char)

strip这个单词可有来头,含义非常多,中台里其实有一些释义出于少儿不宜原因所以没有做过多制作,但还好幸运的你发现了这门单词课程🤔🧐

strip原本的词性就是动词,词源只能追溯到古英语,并没有办法找到很多单词都能寻回的法语或拉丁语里去。由古英语发源的单词,很多时候跟德语更亲近,在那时候的高层人士说的德语中,strip最原本的意思就是:

  1. 除去(衣服、遮盖),这是从14世纪就有的最原本的意思
    He stripped his clothes off before bed. (他在睡前脱掉了衣服)
    He stripped the peel off that orange. (他剥掉了橘子的皮)

  2. 剥夺、除去(所有物、荣耀、地位),这才是19世纪后逐渐延伸出来的意思
    The landlord stripped the peasant off his earnings. (地主夺走了农民的收入)

这两个释义很明显能看出高强度的关联:不管是脱衣服还是除去荣耀,它们的意象都指向“把原本不属于某个事物的、附加的内容,通过外界力量给去除掉”,所以才有了python里面的string.strip(),删去字符串两边的空白。当然lstrip和rstrip在这个基础上就更好理解了,l就是left,r就是right,所以各自代表字符串开头和末尾的空白。除了除去空格,也自定义要除去什么,当然也类似一个人穿了衣服裤子鞋子帽子,

由于各种各样的河蟹原因,中台里或者国内的词典网站里都没有对第一个释义作置顶或扩充解释,但strip最原本的释义就是脱衣服!只有建立了对脱衣服的意象的理解,才能理解为什么后面会有脱去所有物、脱去荣耀、地位之类的意思嘛。

所以以下两个经常被河蟹的拓展内容就作为考试检验放在这里,看看你学完strip之后有没有理解strip:
stripper n. 是什么意思?
strip club 名词词组 是什么意思?

转换进制 数字的前缀

关于数字前缀,维基百科里有来自各语言词源的参照表,有兴趣可去学习一二,在本课不作强制要求。

bin() 转二进制
oct() 转八进制
int() 转十进制
hex() 转十六进制

程序老师们可能从小到大都对数字和进制之类的很敏感,但对这些数字和进制的英文你可能根本就不知道是怎么回事(真是术业有专攻啊!正如我学了语言之后对语言颇有精通,但走到外面吃完饭连算钱都算不清楚),今天就从python几个进制转换的内置函数讲起,让你一口气把数字前缀给学个明白。

首先从如上几个python的内置函数讲起。

bi-

bin()的完整形式是binary,形容词。

binary的前缀来自大名鼎鼎的bi-,在拉丁语中表示2,所以binary的字面意思,就表示“两个(一组)的”。延伸一下:

binary的名词释义,就是“二进制”,所以bin()的功能就很好理解了
binary code 二进制代码

由bi-前缀延展出来的单词还有很多:

bicycle:两个+圈=自行车
(单轮自行车是unicycle,uni-是拉丁语里表示1的前缀;三轮自行车是tricycle,tri-是拉丁语里表示3的前缀)

binocular:两个+眼睛=双筒望远镜
(单筒望远镜是monocular,mono-是希腊语里表示1的前缀)

bilingual:两个+舌头/语言=双语的
(单语的是monolingual;多语的是multilingual,multi-是拉丁语里表示多个点前缀)

bilateral:两个+边=双边的
(单边的是unilateral,多边的是multilateral)

和老师们工作相关的,也有bi开头的单词,比如双周会 - biweekly meeting,双月会 - bimonthly meeting,双年会 - biannually meeting。。。

oct-

oct()的完整形式是octonary,同样也是形容词。

学过binary之后就会发现,octonary跟binary只是前缀不一样而已,所以我们猜都可以猜到,octo-就是拉丁语里表示8的前缀,octonary就表示“八个(一组)的”。

oct(o)-前缀同样也有很多你意想不到的单词:

octopus:章鱼,也叫八爪鱼,为啥?因为octo+pus,八个+脚!

October:怎么回事,突然发现October十月的前缀也是八,难道十月应该是八月的意思?我的初中英语知识狠狠地把我欺骗了?

不光是October把你骗了,其实September,October,November,December都把你骗了,因为它们的字面意思其实分别是:七月,八月,九月,十月,各取的拉丁语中的sept- 7,octo- 8,novem- 9,decem- 10的前缀。

是不是有一种“吓死我了感觉一辈子英语全白学了”的感觉?

其实是因为你只学了英语,但你没有兴趣去了解古代的神话和历史——其实古老的罗马日历,一年的开始是从2月结束,3月开始的(所以闰年多的日子才会加在2月哦)。公元前153年,古罗马元老院修改了日历法,新年正式从1月开始,后面月份的参数就相应地变化了。

再到现在,我们对月份的了解就变成了只是“从1开始往后数,数到第几就是几月”,而没有去系统了解每个月份背后的单词都是什么意思、是怎么来的,所以才会产生前面我描述的“感觉一辈子都被英语骗了”的慌张感。

int()

int()的功能很好理解:将字符串或数字转换为整数,默认该整数是十进制。

int()的完整形式是integer,在拉丁语中由in-(没有) + tangere(触摸)组成,一个东西如果没有被动过,就说明这个东西是“完整”的,所以integer作名词时,表整数。

与integer相关的单词,拓展出来值得学习的有下面几个:
integral adj. 完整的,必要的
integrate v. 使...合并(成为一体)
integrity n. (领土)完整;诚信

python中因为int()默认转换的整数是十进制,所以没有再做冗余的函数把数字处理成十进制,只有一个decimal模块专门调取来提供快速且正确舍入的十进制浮点运算。

所以今天我们要主要研究的其实重点不在integer这个单词,而是decimal,它才是真正的跟数字前缀挂上钩的单词。

如果你真的认真听了前面的课,那你肯定可以直接立刻马上意识到,decimal这个单词的前缀是啥意思?是10。

但是跟December的前缀decem-不一样的是,decimal的前缀是deci-。虽然在拉丁语里都表示10,decem-指代的是基数的10(cardinal),deci-指代的是序数的10(ordinal)。

deci-这个前缀其实有一个非常有趣的历史知识。

由它组成的一个单词,decimation,在古罗马时期(最早记录于公元前471年)它的意义就有一重原始的血腥的色彩,指“在十个人里面抽一个人来砍头”,在15世纪中旬的时候指“收取收入的【十分之一】作为税款”,所以decimation这个单词最通用的意象是“每十个里消除一个”。

古罗马的军队规矩一直都是远近闻名地严格。为了严惩军队里违背军规的人(主要是犯下“怯懦”之罪的人:逃兵、叛兵、不听指令等),军官就会把这些小兵分成十人一组,让每个人抽签,抽到最短的签的人,就会被砍头,或者以其他的方式被杀死,处决者通常是十人组里没有抽到“死签”的剩余的九人。这样的军队管理办法甚至到了一战时期都仍在被法国和意大利的一些部队沿用。
Pasted image 20240424234804.png

所以decimal这个单词,延伸出来的意义就是“和10或1/10有关的”,才有了十进制的意思。

hex()

如果你还能坚持学到这里,并且聪明的你肯定知道hex()是转换为十六进制,然后你基于以上的知识自信地猜测,哈哈,hex肯定就是什么古老的语言里表示16的前缀,那你就大错特错了!

这个前缀正确的形式应该是hexa-,在拉丁语表序数的列表里,hexa-是6的意思。

hexa-系列的单词不是很常见,但仍有一个单词可以举出作为例子:
hexagon n. 六边形
来自hexa- + gon,六个+边/角

消极的学习者记了一个hexagon就觉得自己今天已经学习到位了,但作为优秀的同学,你肯定很好奇,还有那么多边形,他们分别都咋个说?其实从五边形到十边形,构词方式都跟hexagon一样。
Pasted image 20240424234830.png

上图中的前缀,从tri-到deca-,就是从3到10的意思,有兴趣还可以去本节最前面的维基百科网页里查询哈!

值得一提的是美国那个赫赫有名的五角大楼,英语就是Pentagon,你看下图,是不是就是一个标准的五边形呢?
Pasted image 20240424234850.png

讲回来。python内置函数的hex(),完整形式其实是hexadecimal。如果你完整学完了前面的内容,你就会发现,wow,hexadecimal我知道它的意思!原来就是hexa-(6)+decimal(10),所以hexadecimal才是十六进制的意思嘛。

hash()和slice()函数的功能,怎么跟做饭一样?

hash

这一课真的很难讲,因为哈希函数看上去像是很难的东西,老师只能自己去了解个大概,然后就带着这个课程来讲了!

首先解决一个问题:哈希函数为什么要叫“哈希”?

你可能只知道哈希两个字时hash的音译。你或许会直接以为哈希是一个人,是一个叫哈希的人发明了这种函数,就像bool()和布尔值的来源就是发明它的这个人,乔治·布尔(George Boole)。

但其实hash不是一个人,hash只是一种烹饪方法。

先不告诉你hash的具体释义是什么,我们还是去记它的意象。

Pasted image 20240424234942.png Pasted image 20240424234951.png Pasted image 20240424235000.png Pasted image 20240424235008.png
corned beef hash sweet potato hash hamburger hash bacon and egg hash
盐卤牛肉hash 红薯hash 汉堡肉hash 培根蛋hash

看完这几道菜之后有没有发现,这几道hash菜,里面的内容都是先把原料切成一颗一颗的,最后都是被炒成一整锅出来的?

所以hash作动词时,就表示“chop and mix”,意思是把一堆东西剁碎了,再组合。hash作名词时,就是形容用这种方式做出来的菜品,有点类似中文里的“杂炒”。

理解了hash的含义后,你就很容易理解hash()函数的功能。

通过复杂的映射规则,hash()可以把数据打乱、混合,最后生成一系列的哈希值(可以直接就被称作hashes,就像是做出来了一道又一道的杂炒菜一样)。

但是它具体要怎么用,可以用在什么地方,本人就是一无所知了,所以这世界上需要更多这样的文档,让两边的老师都站出来教知识,相信天天都在处理数据的杨老师应该有很多可以讲的吧,但他认为的上课就只是给你找一个网页+发一个pdf而已!
Pasted image 20240424235104.png

此外呢,不知道同学们有没有吃过麦当劳的早餐,或者去吃过那种很西化的brunch(早午餐),里面总是有一道非常经典的早餐菜品,叫土豆饼。土豆饼就像下图一样,是把土豆切成丝、小颗粒,然后把土豆通过鸡蛋和面粉搅和在一起,油煎出来的。所以这种土豆饼在英语里的全名是hashed browned potatoes,意思是被hash过的、被煎成棕色的土豆。久而久之人们觉得这名字太长了,就把它变成hash brown了,保留了做菜过程中的两个步骤:切碎充足+煎。
Pasted image 20240424235130.png

slice

理解了hash之后,slice就更简单了。

slice这个单词最早有记录的意思是在14世纪专门指木头碎下来的渣子和小片。直到15世纪后人们的生活逐渐进步发达、生活中有了更多“片”状的东西之后,slice才用于指代所有一片一片的东西的。

Pasted image 20240424235204.png Pasted image 20240424235212.png Pasted image 20240424235218.png Pasted image 20240424235225.png Pasted image 20240424235232.png Pasted image 20240424235239.png
slice the zucchini meat slice pizza slice bread slice coffee slice slice
切西葫芦 肉片 披萨片 面包片 咖啡味蛋糕块 n. 2. 专门用来给薄片类食物翻面的锅铲
v. 切片 n. 1.(切割过的)片、块

所以slice()在python中的用法直接显而易见:
slice(start, end, step),该切哪切哪。