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嗎?》

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