Python 基础

Python带条件判断的赋值语句

在学C++的时候存在一种一句,a ? b : c。若a为真,返回b,否则返回c。在Python中有多种不同的表达方式。

  • 赋值语句中的if

    • 123 if True else 321
      Out[5]: 123
      
      123 if False else 321
      Out[6]: 321
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15

      - 赋值语句中的 and 和 or

      - ```python
      10 or 20
      Out[7]: 10

      10 and 20
      Out[8]: 20

      0 or 1
      Out[9]: 1

      0 and 1
      Out[10]: 0
    • 短路运算符规则:

      • 表达式从左至右运算。
      • 若 or 的左侧逻辑值为 True , 则短路右侧,返回 or 左侧表达式。若从左到右一直是False,即返回最后一个False。
      • 若 and 的左侧逻辑为 False , 则短路右侧,返回 and 左侧表达式。若从左到右一直为True,即返回最后一个True。
    • 1 and True and 3 and False
      Out[19]: False
      
      1 and True and 3 and 0
      Out[20]: 0
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10

      - Tip: 不建议使用,会伤害可读性。

      - 索引条件赋值

      - 将bool值作为整型索引

      - ```python
      (1,2)[True]
      Out[22]: 2
  • 类型的布尔判断

    • (None or int)('12345')
      Out[26]: 12345
      
      (str or int)('12345')
      Out[27]: '12345'
      
      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



      ## Python dict

      - key value 基础:

      - key 唯一,是不可变的,比如字符串、数子或者元组。故dict可以作为hashTable来使用,数字也可以作为dict的key。
      - value 可为任意数据类型。
      - 布尔判断

      # Python 内置数据结构、函数及操作符

      ## 数据结构

      ### 集合 set

      1. 创建

      1. ```python
      # 创建空集合
      s = set()

      # 创建有元素集合
      s = {para1, para2,...}
      s = set([para1,para2,...]) # set([iterable]) 比如说 string, list
  1. 集合计算

    1. >>> a = set('abracadabra')
      >>> b = set('alacazam')
      >>> a                                  
      {'a', 'r', 'b', 'c', 'd'}
      # 差集 difference
      >>> a - b                              # 集合a中包含而集合b中不包含的元素
      {'r', 'd', 'b'}
      # 并集 union
      >>> a | b                              # 集合a或b中包含的所有元素
      {'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
      # 交集 intersection
      >>> a & b                              # 集合a和b中都包含了的元素
      {'a', 'c'}
      # 对称差 symmetric difference
      >>> a ^ b                              # 不同时包含于a和b的元素
      {'r', 'd', 'b', 'm', 'z', 'l'}
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19

      3. 集合的基本操作

      ```python
      # 添加元素
      s.add(x) # 在 set 中添加 x
      # 添加元素 2
      s.update(l1,l2) # 在 set 中添加多个元素,参数可以是列表、元组、字典
      # 删除
      s.remove(x) # x 不存在会报错
      # 删除 2
      s.remove(x) # x 不存在不会报错
      # 清空
      s.clear() # 清空集合





Priority Queue

priority queue 基础

Dict 字典

dict.get(key, default = None)

OrderedDict

有顺序的 dict, 基本是 stack + dict 的结合体

1
2
3
4
5
popitem(last=True)
The popitem() method for ordered dictionaries returns and removes a (key, value) pair. The pairs are returned in LIFO order if last is true or FIFO order if false.

move_to_end(key, last=True)
Move an existing key to either end of an ordered dictionary. The item is moved to the right end if last is true (the default) or to the beginning if last is false. Raises KeyError if the key does not exist:

内置函数

zip

1
2
3
4
5
6
7
8
9
DBabichev
# 对迭代器进行打包,迭代器的长度可以不一致,返回值也是一个迭代器
>>> a = [1, 2, 3]
>>> b = [4, 5, 6]
>>> list(zip(a,b,range(3)))
[(1, 4, 0), (2, 5, 1), (3, 6, 2)]

>>> list(zip(a, b[1:]))
[(1, 5), (2, 6)]

iter

we can implement iterator using _iter_\

  1. 遍历用法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
for element in iterable:
# do something with element

# create an iterator object from that iterable
iter_obj = iter(iterable)

# infinite loop
while True:
try:
# get the next item
element = next(iter_obj)
# do something with element
except StopIteration:
# if StopIteration is raised, break from loop
break
  1. in 用法,作为快慢指针使用

    1
    2
    3
    4
    5
    6
    7
    def findLongestWord(self, s: str, d: List[str]) -> str:
    d.sort(key = lambda x: (-len(x), x))

    for word in sorted(d, key = lambda x : (-len(x), x)) :
    iter_s = iter(s)
    if all( c in iter_s for c in word) :
    return word
    1. iter() 返回 一个 iterator
    2. ele in iter_s : 执行 next(iter_s) 直到找到 ele,返回 true,iterator 指向下一个。
    3. 如果没有找到:next 执行到尾部之后,或者 iter_s 已经在尾部之后,返回 true。

ord

ord(‘$’): f返回与当前符号作为 Unicode 所对应的整数。

map

1
2
3
map(function, iterables)
function: function to execute for each item
iterable: iterator object
1
2
3
4
5
6
def myfunc(a, b):
return a + b

x = map(myfunc, ('apple', 'banana', 'cherry'), ('orange', 'lemon', 'pineapple'))

>> ['appleorange', 'bananalemon', 'cherrypineapple']

range

  1. range

    1. range(start, stop[, step])
      
      1
      2
      3
      4
      5

      ### pow

      1. ```python
      pow(a,b) # 求 a^b 的数值

reversed()

re

sort()

list.sort([reverse = …]) : inplace 对 list 进行 ascending 排序

sort(list): 返回 sort 的结果

key = lambda x: x.val

使用 lambda 函数作为排序的 key

functools.cmp_to_key

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> from functools import cmp_to_key
>>> def cmp(x, y):
return x - y

>>> a = [2,3,2,1,3,4,5,3]
>>> sorted(a, key = cmp_to_key(cmp))
[1, 2, 2, 3, 3, 3, 4, 5]

>>> def cmp2(x, y):
return y - x

>>> sorted(a, key = cmp_to_key(cmp2))
[5, 4, 3, 3, 3, 2, 2, 1]

操作符

示例 :

1
2
3
a = 0011 1100

b = 0000 1101

赋值 ==

1
2
3
4
5
6
7
8
9
10
11
a = b = [0, 1, 2]

print(a is b)
# True

a[0] = 100
print(a)
# [100, 1, 2]

print(b)
# [100, 1, 2]

将同一个对象赋值给多个 variables

ASCII 转化

  1. ord() 和 chr() 之间的相互转化
1
2
ord('a') = 97
chr(97) = 'a'
描述 实例
& 按位与运算符:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0 (a & b) 输出结果 12 ,二进制解释: 0000 1100
| 按位或运算符:只要对应的二个二进位有一个为1时,结果位就为1。 (a | b) 输出结果 61 ,二进制解释: 0011 1101
^ 按位异或运算符:当两对应的二进位相异时,结果为1 (a ^ b) 输出结果 49 ,二进制解释: 0011 0001
~ 按位取反运算符:对数据的每个二进制位取反,即把1变为0,把0变为1。**~x** 类似于 -x-1 (~a ) 输出结果 -61 ,二进制解释: 1100 0011, 在一个有符号二进制数的补码形式。
<< 左移动运算符:运算数的各二进位全部左移若干位,由”<<”右边的数指定移动的位数,高位丢弃,低位补0。 a << 2 输出结果 240 ,二进制解释: 1111 0000
>> 右移动运算符:把”>>”左边的运算数的各二进位全部右移若干位,”>>”右边的数指定移动的位数 a >> 2 输出结果 15 ,二进制解释: 0000 1111

mod

1
a % b

否定符号

!(exclamation mark)在 python 不适用。

使用 not 来作为所有想用 ! 时候的否定符号。

科学计数法

1
2*(10^9) : 2e9

逻辑运算符 and or

除了 bool 运算的返回值

1
2
3
4
5
6
7
8
9
10
>>> a = 10
>>> b = 20
>>> 0 and b # x and y,如果 x 为 False 就返回 False , 否则返回 y
0
>>> a and b
20
>>> 0 or b # x or y, 如果 x 为 False 就返回 y, 否则返回
20
>>> a or b
10

Python string

isdecimal, isdigit, isnumeric 的区别

ref: https://stackoverflow.com/questions/44891070/whats-the-difference-between-str-isdigit-isnumeric-and-isdecimal-in-python

区别如下表所示,通常我们判断是否为一个数值,使用 isdigit() 看起来比较适用。

1
2
3
4
5
6
7
8
+-------------+-----------+-------------+----------------------------------+
| isdecimal() | isdigit() | isnumeric() | Example |
+-------------+-----------+-------------+----------------------------------+
| True | True | True | "038", "੦੩੮", "038" |
| False | True | True | "⁰³⁸", "🄀⒊⒏", "⓪③⑧" |
| False | False | True | "↉⅛⅘", "ⅠⅢⅧ", "⑩⑬㊿", "壹貳參" |
| False | False | False | "abc", "38.0", "-38" |
+-------------+-----------+-------------+----------------------------------+

Python List

二维列表初始化

  1. 如果按照l=[[0]*m]*n 的方式赋值,得到的结果是指向[0]*m的n个指针。所以如果对l[p][q]=0这样赋值,会对所有list的index为q的位置进行赋值。

  2. 所以要按照一种新方法进行赋值

    1. l = [[0]*m for _ in range(n)]
      
      1
      2
      3
      4
      5
      6
      7
      8


      ## 列表解析

      使用列表 filter 来进行新列表赋值。

      ```python
      [expr for iter_val in iterable if cond_expr]

”+“ 操作符 —— 列表链接

1
2
3
4
5
6
7
8
a = [1,2,3]

b = [4,5,6]

c = a+b

c的结果:[1,2,3,4,5,6]

按照第一个元素进行排序

  1. sort in_place

  2. 按照第一个元素进行 sort

    1. t.sort(key = lambda x: x[0])
      
      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
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69

      3. sorted(list):返回值就是按照第一个元素

      4. reversed : reverse = True 降序,reverse = False 升序


      ## 删除元素

      - Remove all items: `clear()`
      - Remove an item by index and get its value: `pop()`
      - Remove an item by value: `remove()`
      - Remove items by index or slice: `del`
      - Remove items that meet the condition: List comprehensions



      # Python 数据结构实现

      ## Queue

      1. 数据结构特性: First In First Out

      2. 数据操作:

      1. Enqueue : add an item to the queue, overflow should be warned
      2. Dequeue: remove an item from the queue, underflow should be warned
      3. Front: get the front item 最早被压入队列的元素
      4. Rear: get the last item 最后被压入队列的元素

      3. 实现方式

      1. Python list

      2. collection.deque

      1. ```python
      from collections import deque

      # Initializing a queue
      q = deque()

      # Adding elements to a queue
      q.append('a')
      q.append('b')
      q.append('c')

      print("Initial queue")
      print(q)

      # Removing elements from a queue
      print("\nElements dequeued from the queue")
      print(q.popleft())
      print(q.popleft())
      print(q.popleft())

      print("\nQueue after removing elements")
      print(q)

      # output
      Initial queue
      deque(['a', 'b', 'c'])

      Elements dequeued from the queue
      a
      b
      c

      Queue after removing elements
      deque([])
    2. queue.Queue

      1. build - in Python function

      2. functions:

        1. # initiate
          q = Queue(maxsize = 3)
          
          # add element to the queue
          q.put('a')
          
          # get element from the queue
          q.get() # 'a' FIFO
          
          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

          3. Example

          ```python
          # Python program to
          # demonstrate implementation of
          # queue using queue module


          from queue import Queue

          # Initializing a queue
          q = Queue(maxsize = 3)
          # maxmize is the initial size of the queue
          # maxmize = 0: this is an infinite queue

          # qsize() give the maxsize
          # of the Queue
          print(q.qsize()) # 0

          # Adding of element to queue
          q.put('a')
          q.put('b')
          q.put('c')

          # Return Boolean for Full
          # Queue
          print("\nFull: ", q.full()) # Full: True

          # Removing element from queue
          print("\nElements dequeued from the queue")
          print(q.get()) # a
          print(q.get()) # b
          print(q.get()) # c

          # Return Boolean for Empty
          # Queue
          print("\nEmpty: ", q.empty()) # Empty: True

          q.put(1)
          print("\nEmpty: ", q.empty()) # Empty: False
          print("Full: ", q.full()) # Full: False

          # This would result into Infinite
          # Loop as the Queue is empty.
          # print(q.get())

PriorityQueue

1
2
3
4
5
6
from heapq import *
heappush(heap, i) 按照 heap 的大小排序进行
heappop(heap)
heapify(list)
heapreplace(heap, i) 置换,先返回最小的值再进行 push
heappushpop(heap, i) 顾名思义,先 push i,再进行 pop 操作

heapq 中没有接受 key 排序函数的 feature,可以使用(key, task)的符合键来完成排序与 task 不一致的任务。

Tricks

三个布尔变量,有两个或者两个以上为True才返回为True

1
(b||c) if a else (b && c)
1
a if a == b else c
  • Attention: None != False

Python 常用函数

内置

vector 初始化

  1. 给定vector规模的vector初始化。

    1. vector<int> m(cost.size() + 1); // 长度为cost.size()+1, 元素都为0的vector
      vector<vector<vector<strig>>> dp(n) ; //仅指定第第一维的大小
      
      1

自增运算符的区别

  1. a ++ : 先返回,后自增

  2. ++ a:先自增,后返回

  3. 例子

    1. int a = 20  
      c = a ++ // c - 20, a - 21
      b = ++ a // b - 22, 
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18

      ## 队列 queue

      1. 基本操作
      1. 入队,如例:q.push(x); 将x接到队列的末端
      2. 出队,如例:q.pop(); 弹出队列的第一个元素,注意,并不会返回被弹出元素的值。
      3. 访问队首元素,如例:q.front(),即最早被压入队列的元素。
      4. 访问队尾元素,如例:q.back(),即最后被压入队列的元素。
      5. 判断队列空,如例:q.empty(),当队列空时,返回true。
      6. 访问队列中的元素个数,如例:q.size()

      ## C++ string substr()

      1. 成员函数

      1. ```c++
      string substr (size_t pos = 0, size_t len = npos) const;
      // para1:子串开始位置,para2:子串长度

神奇的位操作

判断一个数是否为 2 的幂:

  1. num &(num - 1) == 0

常用的库

Math

comb(a, b) 计算组合数

1
2
3
>>> from math import comb
>>> comb(10,3)
120

collection

Counter

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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
'''
赋值定义和基本使用
'''
>>> from collections import Counter
>>> c = Counter()
# 计数功能
>>> c = Counter('gallahad')
Counter({'a': 3, 'l': 2, 'g': 1, 'h': 1, 'd': 1})
>>> c = Counter({'red': 4, 'blue': 2})
Counter({'red': 4, 'blue': 2})
# 对于 dict 可以合并计数
>>> c = Counter({'red': 4, 'blue': 2, 'blue':3, 'red':12})
Counter({'red': 12, 'blue': 3})
>>> c = Counter(cats = 4, dogs = 8)
Counter({'dogs': 8, 'cats': 4})
# 对于不存在的 key 也可以返回一个 0 的计数
>>> c['flower']
0
# 整体删除某个 key
>>> del c['dogs']
>>> c
Counter({'cats': 4})

'''
elements()
return an iterator over elements repeating each as many as its count.
'''
# 返回一个关于 elements() 的迭代器
>>> sorted(c.elements())
['cats', 'cats', 'cats', 'cats']

'''
most_common([n])
return a list of the n most common elements and their counts from the most common to the least
'''
>>> c = Counter('abracadabra')
Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1})
>>> Counter('abracadabra').most_common(3)
[('a', 5), ('b', 2), ('r', 2)]
>>> c.most_common(2)
[('a', 5), ('b', 2)]

'''
subtract([iterable - or - mapping])
subtract the count from a Counter
'''
>>> c = Counter(a=4, b=2, c=0, d=-2)
>>> d = Counter(a=1, b=2, c=3, d=4)
>>> c.subtract(d)
>>> c
Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})

'''
Other operations supported
'''
sum(c.values()) # total of all counts
c.clear() # reset all counts
list(c) # list unique elements
set(c) # convert to a set
dict(c) # convert to a regular dictionary
c.items() # convert to a list of (elem, cnt) pairs
Counter(dict(list_of_pairs)) # convert from a list of (elem, cnt) pairs
c.most_common()[:-n-1:-1] # n least common elements
+c # remove zero and negative counts

'''
Mathematical Operations
'''
>>> c = Counter(a = 3, b = 1)
>>> d = Counter(a = 1, b = 2)
>>> c + d
Counter({'a': 4, 'b': 3})
>>> c - d
Counter({'a': 2})
>>> c & d
Counter({'a': 1, 'b': 1})
>>> c | d
Counter({'a': 3, 'b': 2})

OrderedDict

1
2
3
4
5
6
dic = OrderedDict()
# move_to_end()
dic.move_to_end(key) 将一个元素移动到有序列表的末尾
# popitem()
dic.popitem(last = False) FIFO
dic.popitem(last = True) LIFO

Bisect

用于数组二分查找算法的调用

1
2
3
4
5
bisect.bisect_left(a, x, lo=0, hi=len(a)) # 返回左插入点
bisect.bisect_right(a, x, lo=0, hi=len(a))
bisect.bisect(a, x, lo=0, hi=len(a)) # 返回的插入点是已存在元素的右侧
bisect.insort_left(a, x, lo=0, hi=len(a)) # 插入并维持有序

1
2
3
4
5
6
def find_gt(a, x):
'Find leftmost value greater than x'
i = bisect_right(a, x)
if i != len(a):
return a[i]
raise ValueError

random

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import random

# 随机整数
random.randint(1, 50)
# inclusive !

# 随机选 iterable 里面的一个
random.choice(nums)

# 多个字符中生成指定数量的随机字符:
print random.sample('zyxwvutsrqponmlkjihgfedcba',5)

# 从a-zA-Z0-9生成指定数量的随机字符:
ran_str = ''.join(random.sample(string.ascii_letters + string.digits, 8))

# abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
result = string.ascii_letters

# 0123456789
result = string.digits


itertools

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# production
>>> prd = itertools.product('ABCD', repeat = 2)
>>> print([*prd])
[('A', 'A'), ('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'A'), ('B', 'B'), ('B', 'C'), ('B', 'D'), ('C', 'A'), ('C', 'B'), ('C', 'C'), ('C', 'D'), ('D', 'A'), ('D', 'B'), ('D', 'C'), ('D', 'D')]

# permutation // with order
>>> perm = itertools.permutations('ABCD', 2)
>>> print([*perm])
[('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'A'), ('B', 'C'), ('B', 'D'), ('C', 'A'), ('C', 'B'), ('C', 'D'), ('D', 'A'), ('D', 'B'), ('D', 'C')]

# combination // without order
>>> comb = itertools.combinations('ABCD', 2)
>>> print([*comb])
[('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'C'), ('B', 'D'), ('C', 'D')]

# combination with replacement // 摸球的时候,小球可以放回袋子里
>>> combwr = itertools.combinations_with_replacement('ABCD', 2)
>>> print([*combwr])
[('A', 'A'), ('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'B'), ('B', 'C'), ('B', 'D'), ('C', 'C'), ('C', 'D'), ('D', 'D')]

Pandas

map(), apply() and applymap()

map()

Python built-in function:

1
2
3
4
5
def myfunc(a, b):
return a + b

x = map(myfunc, ('apple', 'banana', 'cherry'), ('orange', 'lemon', 'pineapple'))
# ['appleorange', 'bananalemon', 'cherrypineapple']

apply()

pandas.DataFrame.apply, pandas 函数,将整行或者整列传入进行处理。

DataFrame.``apply(**func,** axis=0**,** raw=False**,** result_type=None**,** args=()**,**kwds)

1
2
3
4
5
6
7
8
9
10
df
A B
0 4 9
1 4 9
2 4 9

df.apply(np.sum, axis=1)
0 13
1 13
2 13

applymap()

elementwise, 以每单个元素传入进行处理。

DataFrame.``applymap(**func,** na_action=None**)**

1
2
3
4
5
6
7
8
     0      1
0 1.000 2.120
1 3.356 4.567

df.applymap(lambda x: len(str(x)))
0 1
0 3 4
1 5 5

其他参考

Python 常用操作的时间复杂度

ref: https://www.ics.uci.edu/~brgallar/week8_2.html

Python 为什么不能给 integer 一个指针

Python 中的 integer 是 immutable 的 https://stackoverflow.com/questions/15148496/passing-an-integer-by-reference-in-python