17个高效技巧:一行python,十行C++

目录

1、交换变量值

2、将列表中的所有元素组合成字符串

3、查找列表中频率最高的值

4、检查两个字符串是不是由相同字母不同顺序组成

5、反转字符串

6、反转列表

7、转置二维数组

8、链式比较

9、链式函数调用

10、复制列表

11、字典 get 方法

12、通过「键」或「值」排序字典元素

13、For Else

14、转换列表为逗号分割符格式

15、合并字典

16、列表中最小和最大值的索引

17、移除列表中的重复元素


看到本文标题中“一行python,十行C++”(开发效率),我自己都不服;但我还有一句话没说:十行C++,一行python(速度)。

这17个技巧中有很多非常适合文本处理的技巧,而文本处理的应用领域可以非常广泛。

简洁往往意味着晦涩难懂,是时候见证基础强弱了。

1、交换变量值

>>> a,b=5,10
>>> print(a,b)
5 10
>>> a,b=b,a
>>> print(a,b)
10 5
>>>

点评:语句a,b=b,a的作用是交换对象a、b的值。拨开迷雾见真章:

>>> a,b=5,10
>>> id(a)
1842769088
>>> id(b)
1842769248
>>> a,b=b,a
>>> id(a)
1842769248
>>> id(b)
1842769088
>>> id(10)
1842769248
>>> id(5)
1842769088
>>>

2、将列表中的所有元素组合成字符串

>>> a=['Python','is','awesome']
>>> print(" ".join(a))
Python is awesome
>>>

点评:看到python在词语处理方面的优势了吧?还有很多。

3、查找列表中频率最高的值

方式一:
>>> a=[1,2,3,1,2,3,2,2,3,4,1]
>>> print(max(set(a),key=a.count))
2
方式二:
>>> from collections import Counter
>>> cnt=Count(a)
>>> cnt=Counter(a)
>>> print(cnt.most_common(3))
[(2, 4), (1, 3), (3, 3)]
>>>

点评:python中一些语句的用法把C++中的多态特性发挥到极致,比如max(set(a),key=a.count)。等价过程如下:

>>> a=[1,2,3,1,2,3,2,2,3,4,1]
>>> aset=set(a)
>>> temp=[]
>>> for i in aset:
      temp.append((a.count(i),i))
>>> temp.sort(key=lambda x:x[0],reverse=True)
>>> temp
[(4, 2), (3, 1), (3, 3), (1, 4)]
>>> print(temp[0][1])
2
>>>

cnt.most_common(3)语句可以得出频率最大的前三个值,但是是以元组构成的列表表示出来。cnt和temp类似,只不过cnt各元组中第一项是值,第二项是频率,和temp中各元组的第一、二项含义相反。

4、检查两个字符串是不是由相同字母不同顺序组成

>>> from collections import Counter
>>> str1='abcde'
>>> str2='dbeac'
>>> Counter(str1)
Counter({'a': 1, 'b': 1, 'c': 1, 'd': 1, 'e': 1})
>>> Counter(str2)
Counter({'d': 1, 'b': 1, 'e': 1, 'a': 1, 'c': 1})
>>> Counter(str1)==Counter(str2)
True
>>> {'a': 1, 'b': 1, 'c': 1, 'd': 1, 'e': 1}=={'d': 1, 'b': 1, 'e': 1, 'a': 1, 'c': 1}
True
>>>

5、反转字符串

方式一:
>>> a='abcdefghijklmnopqrstuvwxyz'
>>> print(a[::-1])
zyxwvutsrqponmlkjihgfedcba
>>> num=1234567
>>> print(int(str(num)[::-1]))
7654321
方式二:
>>> reversed(a)
<reversed object at 0x000001EFA897A4E0>
>>> for c in reversed(a):print(c,end="")
zyxwvutsrqponmlkjihgfedcba
>>>

点评:int(str(num)[::-1])是对a[::-1]的拓展应用。

6、反转列表

>>> a=[5,4,3,2,1]
>>> print(a[::-1])
[1, 2, 3, 4, 5]
>>> for ele in reversed(a):print(ele,end="")
12345
>>> l=list(reversed(a))
>>> l
[1, 2, 3, 4, 5]
>>>

点评:序列都可用类似a[::-1]的形式反转。

7、转置二维数组

>>> original=[['a','b'],['c','d'],['e','f']]
>>> transpoed=zip(*original)
>>> print(list(transpoed))
[('a', 'c', 'e'), ('b', 'd', 'f')]
>>>

点评:数组、矩阵的行列互换可通过zip轻松实现。

8、链式比较

>>> b=6
>>> print(4<b<7)
True
>>> print(1==b<20)
False
>>>

点评:这种pythonic比较表达式语句更贴近数学表达。

9、链式函数调用

>>> def product(a,b):return a*b
>>> def add(a,b):return a+b
>>> b=True
>>> print((product if b else add)(5,7))
35
>>>

点评:以b作为加法、乘法运算的标志,非常灵活、简洁的用法。

10、复制列表

方式一:
>>> a=[1,2,3,4,5]
>>> b=a
>>> print(a,b)
[1, 2, 3, 4, 5] [1, 2, 3, 4, 5]
>>> b[0]=10
>>> print(a,b)
[10, 2, 3, 4, 5] [10, 2, 3, 4, 5]
方式二:
>>> a=[1,2,3,4,5]
>>> b=a[:]
>>> b[0]=10
>>> print(a,b)
[1, 2, 3, 4, 5] [10, 2, 3, 4, 5]
方式三:
>>> a=[1,2,3,4,5]
>>> b=list(a)
>>> b[0]=10
>>> print(a,b)
[1, 2, 3, 4, 5] [10, 2, 3, 4, 5]
方式四:
>>> a=[1,2,3,4,5]
>>> print(a.copy())
[1, 2, 3, 4, 5]
>>> from copy import deepcopy
>>> l=[[1,2],[3,4]]
>>> l2=deepcopy(l)
>>> print(l2)
[[1, 2], [3, 4]]
>>>

点评:复制对象的时候一定要注意新对象与原对象的关系,特别要区分浅复制与深复制。

11、字典 get 方法

>>> d={'a':1,'b':2}
>>> print(d.get('c',3))
3
>>>

点评:通过d.get('c',3)比通过d[‘c’]的形式访问字典更安全。

12、通过「键」或「值」排序字典元素

方式一:
>>> d={'apple':10,'orange':20,'bababa':5,'rotten tomato':1}
>>> print(sorted(d.items(),key=lambda x:x[1]))
[('rotten tomato', 1), ('bababa', 5), ('apple', 10), ('orange', 20)]
方式二:
>>> from operator import itemgetter
>>> print(sorted(d.items(),key=itemgetter(1)))
[('rotten tomato', 1), ('bababa', 5), ('apple', 10), ('orange', 20)]
方式三:
>>> print(sorted(d,key=d.get))
['rotten tomato', 'bababa', 'apple', 'orange']
>>>

点评:排序的时候,要注意区分排序的依据与排序的内容。此外,在用max()、min()等的时候也一样要注意。

13For Else

>>> a=[1,2,3,4,5]
>>> for el in a:
      if el==0:
             break
else:
      print('did not break out of for loop')
did not break out of for loop
>>>

点评:通过for..else…和if…break…的组合运用,可以不用额外增设某些判断标记。

14、转换列表为逗号分割符格式

类型一:
>>> items=['foo','bar','xyz']
>>> print(",".join(items))
foo,bar,xyz
类型二:
>>> numbers=[2,3,5,10]
>>> print(",".join(map(str,numbers)))
2,3,5,10
>>> data=[2,'hello',3,3.4]
>>> print(",".join(map(str,data)))
2,hello,3,3.4
>>>

点评:在文本处理与文件读写的时候这种转换处理简直不要太帅,特别是map、eval等的灵活运用。

15、合并字典

方式一:
>>> d1={'a':1}
>>> d2={'b':2}
>>> print({**d1,**d2})
{'a': 1, 'b': 2}
方式二:
>>> print(dict(d1.items() | d2.items()))
{'b': 2, 'a': 1}
方式三:
>>> d1.update(d2)
>>> print(d1)
{'a': 1, 'b': 2}
>>>

点评:注意两点,d1.items()返回的不是list;另外就是**d1。

>>> def kw(*,a=9):
      return a+10
>>> d1={'a':1}
>>> kw(**d1)
11
>>> d1={'a':1}
>>> d2={'b':2}
>>> {**d1,**d2}
{'a': 1, 'b': 2}
>>> dict(a=1,b=2)
{'a': 1, 'b': 2}
>>>

16、列表中最小和最大值的索引

>>> lst=[40,10,20,30]
>>> def minIndex(lst):
      return min(range(len(lst)),key=lst.__getitem__)
>>> def maxIndex(lst):
      return max(range(len(lst)),key=lst.__getitem__)
>>> print(minIndex(lst))
1
>>> print(maxIndex(lst))
0
>>>

点评:这里求最大值、最小值的依据key和之前排序的依据key含义类似,要和返回值(也就是正在处理的数据)区别,依据key不必是正在处理的数据,也可以是基于数据的某种映射,本例中key就建立起从数字x(0-len(lst)-1)到lst[x]的映射。

17、移除列表中的重复元素

方式一:
>>> items=[2,2,3,3,1]
>>> newitems=list(set(items))
>>> print(newitems)
[1, 2, 3]
方式二:
>>> from collections import OrderedDict
>>> items=['foo','bar','bar','foo']
>>> print(list(OrderedDict.fromkeys(items).keys()))
['foo', 'bar']
>>>

点评:这里主要通过set和OrderedDict.fromkeys去重。

>>> a=[1,2,3,1,2,3]
>>> OrderedDict.fromkeys(a)
OrderedDict([(1, None), (2, None), (3, None)])
>>>

取材来源:微信公众号 Python专栏 的文章《17个Python的牛逼骚操作,你都OK吗?》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章