python---奇技淫巧(不定时更新)

编程语言的面试,除了核心知识点和语法的考察外,还会有一些考察面试者语言熟练程度的小问题,这些问题虽然涉及的都是一些基本知识点,但是需要使用者能做到活学活用,见多识广,化繁为简。解决同样一个问题,别人写了十几行代码,你却能两三行轻描淡写的搞定,那你的机会就会大大增加,下面就来看一下python里的小trick

1.变量交换

想到变量交换,很多人第一想法就是创建一个中间变量temp来中转一下,这样写没有问题,但是太繁琐,python里一行代码就可以完成这个操作

x,y = 10, 20
x,y = y,x
print(x,y)
>>20 10

2.序列的反转

这里使用切片的方式,将第三个参数设为-1,表示反向

a= [1,2,3,4,5]
b= 'hello'
print(a[::-1])
>>[5, 4, 3, 2, 1]
print(b[::-1])
>>'olleh'

list的反转有专门的函数reverse(), a.reverse()会直接修改a的顺序,没有返回值

3.链式比较

我们有个变量a,要判断它是否大于1小于2,一般会想到使用and 关键字连接两次判断,其实python里可以直接写成数学公式一样的比较,

a=1.5
if 1<a<2:
  print('yes')
>>yes
b= 2<a<3
>>false

4.查找list 中出现次数最多的元素

这个问题解决方法有很多,最简单的就是遍历list,一个个的计算出现次数和上一个比,如果次数大于上一个就替换上一个,否则继续使用上一个元素做比较,这种方法没什么好说的。还有一种方法就是使用collections 模块的Counter方法,这个方法可以一次性返回每个元素出现的次数,返回包含tuple的list(这个方法还可以用来检查两个单词是不是字母相同的)

from collections import Counter
a=[1,2,2,3,3,3]
c=Counter(a)
print(c)
>>Counter({3: 3, 2: 2, 1: 1})
a.most_common(1)[0][0]
>>3

还有一种更简单的方法,是用max函数,一般我们使用max函数只关注第一个参数,其实第二个参数有时有画龙点睛的作用
max函数的定义为:
max(iterable, key, default)
第二个参数是用来处理iterable里每一个的值的,一般为lambda函数,处理完每一个元素后再来比较max,

a=[1,2,2,3,3,3]
m =max(set(a), key=a.count)
>>3

试想面试中,你这行代码一写,绝对在一众平庸的答案中脱颖而出~~

5.zip函数

这个函数可能平时不怎么用到,但是当你需要它的时候,一定要记得它,因为它能为你节省几十行代码
这个函数的作用是让多个可迭代的对象相同位置的元素打包成元组,最后返回这些元组组成的列表。如果多个可迭代对象的长度不一样,则只取最短的那个长度

a=[1,2,3]
b=[4,5,6]
c=[7,8,9,10]
ab=zip(a,b)
>>[(1,4),(2,5),(3,6)]
ac=zip(a,c) 
#注意,python2里直接返回列表,python3返回的是个对象,需使用list函数查看结果,
#并且为了节约内存,zip对象只能访问一次!
>>[(1,7),(2,8),(3,9)]
zip(*ab)
>>[(1,2,3),(4,5,6)]

另外,python里我们可以使用星号(*)来传递列表参数到函数中去,星号会自动把列表解压成单个参数:

def foo(a,b):
    print(a,b)
L=(1,'a')
foo(*L)
>>1 'a'

利用这个属性我们可以把zip 压缩过的结果,再解压回来

a=[1,2,3], b=['a','b','c']
zp=zip(a,b)
zip(*zp)
>>[(1, 2, 3), ('a', 'b', 'c')]

6.查看对象大小

python标准库里有很多非常实用的工具,比如这里我们就可以使用sys模块的getsizeof()方法
获得对象占用空间

7. for else

else 这个语句不止可以和if 搭配,和for 也能成双成对,
当for 语句迭代完后就会进入else语句,所以一般情况下这个else语句总是会执行的,如果想跳过,就需要在
for语句后面使用break强制跳出for 循环。

for i in range(10):
     if i == 5:
         print('get it')
          break#注意,这里必须调用break跳出,不然迭代完成后就会进入else里!
else:
     print('no found!')
>> get it

8. @staticmethod 和 @classmethod

类的方法有3种,staticmethod装饰的静态方法,classmethod修饰的类方法,以及不带装饰器的普通方法(实例方法)。
staticmethod修饰的方法叫静态方法, 比较简单,它修饰的是可以直接通过类来调用的方法,这个方法不需要把self作为第一个参数,就像是把一个普通函数放到类里面一样。不仅类可以直接调用,实例也可以

class st:#其实静态方法用处不大,还不如直接把函数拿到类外面单独定义
      @staticmethod
      def print_str(s):
            print(s)

st1=st()
st1.print_str('aaa')
>>aaa
st.print_str('bbb')
>>bbb

classmethod修饰的类方法还是很有用的,这种方法第一个参数是这个类本身,一般我们用cls表示,有了这个参数,我们就有了掌控整个类的能力,比如直接调用构造函数init()来创建实例
一个很有用的场景是:假如我们有个类Person,在构造函数里初始化用户的年龄,就像这样
p1 = Person(20)
这样很好了,但是可不可以通过生日也能创建一个person呢?就像这样:
p2 = Person.from_birth('1999')
classmethod 就能实现这个想法

from datetime import date 
class Person:
      def __init__(self, age):
            self.age=age
      
      @classmethod
      def from_birth(cls, birth):
            age=date.today().year - birth
            return cls(age)

p1=Person(20)
p2=Person.from_birth(1999)
p1.age
>>20
p2.age
>>20

9. 字典的遍历和顺序问题

在python2 中,字典的序列是无序的,即字典里键实际的顺序和你插入的顺序不一样,但是在python3 中,
绝大多数情况下字典的顺序和插入的顺序是一致的,但要注意,在某些情况下,这个有序是不可靠的,所以,即使是python3,要确保字典有序,请使用OrderedDict来包装字典

capitals = { 
                     'Gujarat' : 'Gandhinagar', 
                     'Maharashtra' : 'Mumbai', 
                     'Rajasthan' : 'Jaipur', 
                     'Bihar' : 'Patna'
                    }
for c in capitals:
        print(c)

# python2 里和插入顺序不同
Rajasthan
Maharashtra
Bihar
Gujarat

#python3 里和插入顺序相同
Gujarat
Maharashtra
Rajasthan
Bihar

# 使用OrderedDict确保字典有序
from collections import OrderedDict 
capitals = OrderedDict([ 
                                 ('Gujarat', 'Gandhinagar'), 
                                 ('Maharashtra', 'Mumbai'), 
                                 ('Rajasthan', 'Jaipur'), 
                                 ('Bihar', 'Patna') 
                                ])

字典的遍历有三种方式:

  1. 遍历key值
# 遍历key有两种方式:
a={'name':'jack', 'age':23}
for i in a:
  print(i)

for i in a.keys():
  print(i)

#输出: 
name age
  1. 遍历value值
a={'name':'jack', 'age':23}
for i in a.values():
  print(i)
#输出 
jack 23
  1. 遍历 key, value 对
a={'name':'jack', 'age':23}
for k ,v in a.items():
  print(k,v)
#输出 
name jack
age 23

10. 变量的打包和解包

  • list 变量的打包解包使用一个星号(*)
    如果一个函数有不定个数的参数时要怎么写?比如写一个累加函数,这个函数可以接受任意多个输入参数,这个时候就要用到变量的打包
def mySum(*args): 
    sum = 0
    for i in range(0, len(args)): 
        sum = sum + args[i] 
    return sum 
  
print(mySum(1, 2, 3, 4, 5)) 
print(mySum(10, 20)) 
#输出
15
30

如果一个函数有很多个参数,我们可不可以一次性传入而不是一个个传入?这就用到变量的解包写法

def fun(a, b, c, d): 
    print(a, b, c, d) 

my_list = [1, 2, 3, 4]  
fun(*my_list) 
#输出
(1, 2, 3, 4)
  • dict变量的打包解包使用两个星号(**)
    字典变量就是python里的关键字参数,比如:
# 这是解包
def person(name,age):
    print('name is ' + name)
    print('age is ' + age)

d= {'age':‘20’, 'name': 'jack'}
person(**d)
#输出:
name is jack
age is 20

# 这是打包
def person2(**kwargs):
    for key in kwargs: 
        print("%s = %s" % (key, kwargs[key]))
persons(name='tom', addr='china')
#输出
name = tom
addr = china

11. 位运算

位运算就是把数字转成二进制形式再进行运算,相对于十进制的加减乘除,位运算符有以下几种:
(下表中变量 a 为 60,b 为 13,通过bin函数查看二进制:a = 0011 1100, b = 0000 1101)


tb.png

看完了上面是不是觉得位运算也没啥用?其实不然,位运算在某些情况下能显著的提高代码效率
比如x&1等于1时x 为奇数,反之为偶数。再比如x>>1 右移1位表示除以2,左移一位表示乘以2

12. 分组统计

对于列表,有一个很常见的需求,就是列表中按照某个条件来统计相应的元素或元素数量,
比如一个包含很多人名的列表,现在需要统计每个名字长度下有哪些人,常见的写法是:

d=['jack', 'mayun','pony','lacky','john','steve','matthew']
dg = {}
for i in d:
    if len(i) not in dg:
        dg[len(i)]=[i]
    else:
        dg[len(i)].append(i)
#输出:
{4: ['jack', 'pony', 'john'], 5: ['mayun', 'lacky', 'steve'], 7: ['matthew']}

因为不知道元素长度是否已经在dg的key里面了,所以每次都要通过if len(i) not in dg检查。实际上python里字典有一个很好用的方法setdefault,就是为了解决这个问题的:

for i in d:
    dg.setdefault(len(i), []).append(i)
#输出:
{5: ['mayun', 'steve', 'lacky'], 4: ['jack', 'pony', 'john'], 7: ['matthew']}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,558评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,002评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,024评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,144评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,255评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,295评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,068评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,478评论 1 305
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,789评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,965评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,649评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,267评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,982评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,800评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,847评论 2 351

推荐阅读更多精彩内容