Python Basic Notes

1 Data structure

1.1 Initialization

<1> List, Tuple, Set and Dictionary

  • Iteratablity: All are iterable. emumerate(list) & dict.item() in for loop
  • Mutablity
  • Order
  • Duplicates
# cannot be used in loop 
my_list_1d = []
my_list_2d = [[]]

my_tuple = ()
my_set = set()
my_dict = {}

# can be used in loop
my_list_1d = [0] * n
my_list_2d = [[0] * n for _ in range(n)]

my_tuple = ((0, 1, 2), (3, 4, 5), (6, 7, 8))
my_set = {1, 2, 3, 4, 5}
my_dict = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}

<2> Nested Dictionary

dictionary keys are not limited to strings and tuples; they can be any immutable type. This includes integers, floats, strings, tuples

# HashTable
my_hashtable = {}  # {key: value}

# HashTable = {string: set}
s ={'number':{1,2,3,4}}
print(s['number']) # {1,2,3,4}
print(list(s['number'])[0]) # 1

# HashTable = {string: dict}
# This can represent the weighted graph
s ={'There':{'are':1,'is':1}}
print(s['There']) # {'are':1,'is':1}
print(s['There']['are']) # 1

# HashTable = {string: list}
s ={'number':[1,2,3,4]}
print(s['number']) # [1,2,3,4]
print(s['number'][0]) # 1

# HashTable = {tuple: list}
s = {(0,1,0):['eat', 'tea', 'ate']}

HashTable + tuple + list: LeetCode 49. Group Anagrams
HashTable + set: LeetCode 36. Valid Sudoku

# Unweighted Graph representation using an adjacency list
graph = {
    "A": ["B", "C"],
    "B": ["A", "D", "E"],
    "C": ["A", "F"],
    "D": ["B"],
    "E": ["B", "F"],
    "F": ["C", "E"]
}

print("Graph Adjacency List:")
for node, edges in graph.items():
    print(f"{node}: {', '.join(edges)}")


# Weighted Graph representation
graph = {
    'A': {'B': 2, 'C': 3},
    'B': {'A': 2, 'D': 4, 'E': 2},
    'C': {'A': 3, 'F': 5},
    'D': {'B': 4},
    'E': {'B': 2, 'F': 3},
    'F': {'C': 5, 'E': 3}
}

# Access the weight of the edge from A to B
print(f"Weight from A to B: {graph['A']['B']}")


1.2 Add method

List uses .append()
Set uses .add()
dictionary uses my_dict[key] = value

<1> Syntax

# list
my_list.append(value) # O(1)
my_hashmap[key].append(value) # O(1)

# set
my_set.add(key) # O(1)
my_hashset[key].add(value) # O(1)

# dictionary or hashtable
my_dict[key] = value # O(1)
my_dict[key][] = value # O(1)
my_dict[key][] = value # O(1)

Note: key is unique, and only includes hashable or immutable type(number, string, tuple)

<2> Example

ans = collections.defaultdict(list)
strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
for s in strs:
    count = [0] * 26
    for c in s:
        count[ord(c) - ord("a")] += 1
    ans[tuple(count)].append(s)
return ans.values()

# Output
'''
defaultdict(<class 'list'>, {(1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0): ['eat', 'tea', 'ate'], 
(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0): ['tan', 'nat'], 
(1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0): ['bat']})
'''

Inspo: LeetCode 242. Valid Anagram and LeetCode 49. Group Anagrams


1.3 - append(a) vs. append(a[:])

backtracking promising function

res.append(path) # 数值会随着改变而改变,结果会出问题
res.append(path[:]) # 暂存每一个时刻的path

Inspo: LeetCode 78. Subsets


1.4 - if i in dict.keys() vs. if i in dict.values()

count = {1: 1, 2: 1}
print(count.keys())
print(count.values())

# Output
'''
dict_keys([1, 2])
dict_values([1, 1])
'''

If you wanna output a list which is the dictionary keys or values,you need to use list()

print(list(count.keys()))
print(list(count.values()))

# output
'''
[1,2]
[1,1]
'''

Inspo: LeetCode 217. Contains Duplicate

2 Operators

2.1 Operators can be commonly used in if condition

  • Comparison operators: ==, !=, <, >, <=, >=
  • Membership operators: in, not in
  • Identity operators: is, is not
  • Logical operators: and, or, not
if a < b and c > d:
    # Do something

if e == f:
    # Do something

if g in some_list:
    # Do something

if variable is None:
    # Do something

if not boolean_value: 
	# If any data structure is empty, it could be considered as False.
	# For example, list = [] represents Flase in boolean expression
	# if not list, then return True
'''
LeetCode 20.Valid Parenthesis
'''

2.2 Other Operators

  • Arithmetic operators
    +: Addition
    -: Subtraction
    *: Multiplication
    /: Division
    %: Modulus (Remainder)
    **: Exponentiation (Power)
    //: Floor Division

  • Bitwise operators
    &: Bitwise AND
    |: Bitwise OR
    ^: Bitwise XOR (Exclusive OR)
    ~: Bitwise NOT (Inversion)
    <<: Bitwise left shift
    >>: Bitwise right shift

3 List Slicing

3.1 Syntax

Value 1 2 3 4 5 6 7 8
Positive Index 0 1 2 3 4 5 6 7
Negative Index -8 -7 -6 -5 -4 -3 -2 -1
object[start:end:step]

'''
object可以是list, tuple, string
start为起始位置,默认从头开始
end为终止位置,默认到结尾
step为步长,默认step = 1
'''

3.2 Example

无论是正序还是倒序,index数值遵循上述顺序,输出永远遵循左闭右开[start,end)

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

print(a[1]) 
print(a[:-1]) # 输出除了最后一个元素
print(a[:]) # 正序全输出
print(a[::-1]) # 倒序全输出
print(a[2::-1]) # [2,结尾]的倒序输出
print(a[5:2:-1]) # [5,2)的倒序输出

# Output
'''
2
[1,2,3,4,5,6,7]
[1,2,3,4,5,6,7,8]
[8,7,6,5,4,3,2,1]
[8,7,6,5,4,3]
[5,4,3]
'''

Citation: Python切片操作(详细版)

4 Print

name = 'Frank'
age = 24

# 三种方法f'{}', '{}'.format, %object
print(f'My name is {name}. I am {age} years old.')
print('My name is {1}. I am {0} years old.'.format(age,name))
print('My name is %s.'%name,'I am %d years old.'%age)

# Output
'''
My name is Frank. I am 24 years old.
'''

Citation: Python格式化的3种方法

5 Return

def中无return,则默认返回None,退出函数
defreturn无参数,与上述情况相同
defreturn有参数,返回参数

6 String Operations

<1> use split() to break down the string

s = 'www.doiido.com.cn'
print(s.split('.')) # split by '.', return a list
print(s.split('.')[1]) # split by '.' and then take s which index = 1, return a string
print(s.split('.',2)) # split twice(i.e. two '.'), return a list

# Output
'''
['www', 'doiido', 'com', 'cn']
doiido
['www', 'doiido', 'com.cn']
'''

<2> looping operations
inspo: LeetCode 17. Letter Combinations of a Phone Number

s = ''
letters = 'abcdef'
for l in letters:
    s += l
    print(s)
s = s[:-1]
print(s)
s = ''
letters = ['abc','def']
for l in letters:
    s += l
    print(s)
s = s[:-1]
print(s)

7 Common Functions


7.1 range()

# Principle
range(start=0:end:step=1)

# Examples
range(5) # [0,5)的int型
range(0,5) # [0,5)的int型
range(0,5,2) # [0,5)的int型, 步长为2
range(3,0,-1) # [3,0)的int型,倒序,步长为1

# Output
'''
[0,1,2,3,4]
[0,1,2,3,4]
[0,2,4]
[1,2,3]
'''

7.2 len() sum() append() pop() sort()

len() will return the length of shape that corresponds to axis 0.

# For a Simple (1-Dimensional) List
simple_list = [1, 2, 3, 4, 5]
print(len(simple_list)) # 5, which is the number of elements in the list

# For a Nested (2-Dimensional) List:
nested_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
rows = len(nested_list) # the number of the sublists
cols = len(nested_list[0]) # the number of elements in the first sublist
shape = (rows, cols)  # The shape is (3, 3)

# string
my_string = "Hello World"
print(len(my_string))  # 11

# tuple
my_tuple = (1, 2, 3)
print(len(my_tuple))  # 3

# dictionary
my_dict = {'a': 1, 'b': 2, 'c': 3}
print(len(my_dict))  # 3

# set
my_set = {1, 2, 3, 3}
print(len(my_set))  # 3 (since sets only count unique elements)

sum() is only used for 1-D sum.


7.3 enumerate() items() zip() reversed() sorted()

.items(), enumerate(), zip(), reversed(), sorted()

# enumerate()
list = [1,2,3]
for item in enumerate(list): # return a tuple
    print(item)

for i,v in enumerate(list):
    print(i,v)

# .item()
dict = {'gallahad': 'the pure', 'robin': 'the brave'}
for item in dict.items(): # return a tuple
    print(item)

for k,v in dict.items():
    print(k,v)

# Output
'''
(0, 1)
(1, 2)
(2, 3)

0 1
1 2
2 3

('gallahad', 'the pure')
('robin', 'the brave')

gallahad the pure
robin the brave
'''

reversed()

# 例1 倒序输出,并存入结果数组
dict = {0: 0, 1: 3, 2: 2, 3: 1, 4: 0, 5: 0, 6: 0}
res = []
for i in reversed(range(1, len(dict))): # for i in range(len(dict)-1, 0, -1):
    res.append(dict[i])
print(res)

# Output
'''
[0, 0, 0, 1, 2, 3]
'''

sorted

def beamSearchV2(self, pre_words, beamK, param_lambda, maxToken):
        top_beam = [(pre_words.split(), 0)]

        while True:
            tmp = []
            for sentence, score in top_beam:
                if "</s>" in sentence or len(sentence) > maxToken:
                    return StringDouble.StringDouble(" ".join(sentence), score)  # Return type adjusted for simplicity

                dic_next_word = self.graph.getGraph().get(" ".join(sentence), {})

                for next_word, prob in dic_next_word.items():
                    tmp_sentence = sentence + [next_word]
                    tmp_score = score + (math.log(prob) / (len(tmp_sentence) ** param_lambda))
                    tmp.append((tmp_sentence, tmp_score))

            top_beam = sorted(tmp, key=lambda x: x[1], reverse=True)
            if len(top_beam) > beamK:
                top_beam = top_beam[:beamK]

7.4 sort() reverse()

  • list.sort(): This will sort the list in place in ascending order.
  • list.sort(reverse=True): This will sort the list in place in descending order.
numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
numbers.sort()
print(numbers)  # Output will be the sorted list in ascending order

numbers.sort(reverse=True)
print(numbers)  # Output will be the sorted list in descending order

words = ['banana', 'apple', 'cherry']
words.sort(key=len)
print(words)  # Output: ['apple', 'banana', 'cherry'], sorted by length of the word

Remember that sort() is a method of list objects and can't be used with other iterables like tuples or dictionaries directly. For those, you would typically use the sorted() function, which returns a new sorted list and leaves the original iterable unchanged.


7.5 next(iter())

# look the first item
dataset = 
dataloader = 
next(iter(dataset)) # first data point
next(iter(dataloader)) # first batch (has batch_size images)

7.6 if continue if break

  • continue跳过当前条件,i+1,继续向下循环。可用于跳过某项,或去重匹配
  • break跳出循环
# if continue
res = []
for i in range(5)
	if i == 3:
		continue
	res.append(i)
print(res)

# if break
res = []
for i in range(5):
	if i == 3:
		break
	res.append(i)
print(res)

# Output
'''
[0, 1, 2, 4]
[0, 1, 2]
'''

Inspo: LeetCode 90. Subsets II


7.7 math.ceil() math.floor() round() int()

return int type


7.8 .join()

https://blog.csdn.net/weixin_50853979/article/details/125119368

7.9 assert

x = "hello"

#if condition returns True, then nothing happens:
assert x == "hello"

#if condition returns False, AssertionError is raised:
assert x == "goodbye"

8 Read / Write Files

# There is a result list
prediction = ['Sam', 'Frank', 'Lucy', 'Sherry']

# If there is not a file called 'p.csv', then create one.
# with open() can close the file automatically.
# When you run agian, the original file will overwrite
with open('p.csv', 'w') as f:
    f.write('id,category\n') # first line

    for i, v in enumerate(prediction): # write the result list into the file
        f.write(f'{i},{v}\n')
id category
0 Sam
1 Frank
2 Lucy
3 Sherry

Read the text into a set of words from the file (Tokenization)

file_path = '../test.txt'

with open(file_path, 'r') as file:
    for line in file:
        words = line.strip().split()

Read the text into a set of sentences from the file

file_path = '../test.txt'

with open(file_path, 'r') as file:
    for line in file:
        words = line.strip()
text = "   Hello,    world!   "
text.strip()
text.split()
" ".join(text.split())
# output
'''
"Hello,    world!"
['Hello,', 'world!']
"Hello, world!"
'''
sentences = ['i like cat', 'i love coffee', 'i hate milk']
sentences_list = " ".join(sentences).split() # ['i', 'like', 'cat', 'i', 'love'. 'coffee',...]
vocab = list(set(sentences_list))
word2idx = {w:i for i, w in enumerate(vocab)}
idx2word = {i:w for i, w in enumerate(vocab)}

V = len(vocab)
# Convert a string to a list of characters
a = 'hello'
a = list(a)
print(a)

# Convert a sentence to a list of words
b = 'hello guys'
print(b.split())

# Convert a list of sentences to a list of words
c = ['hello guys','My name is Frank','Good name']
word_list = " ".join(c).split()
print(word_list)
word_list = list(set(word_list))

print(word_list)

9 Tricks

9.1 List Comprehension

List Comprehension Official Document

# list of numerical variables
numerical_features = [feature for feature in dataset.columns if dataset[feature].dtypes != 'O']

9.2 - lambda x:

tmp = [('I', 0.1), ('I like', 0.2), ('I like you', 0.5)]
top_beam = sorted(tmp, key=lambda x: x[1], reverse=True)

9.3 [*range(10)] is equvalent to list(range(10))

print([*range(10)])
print(*range(10))
print(list(range(10)))

# Output
'''
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
0 1 2 3 4 5 6 7 8 9
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
'''

9.4 map()


9.5 nums[l], nums[r] = nums[r], nums[l]

while l < r:
	nums[l], nums[r] = nums[r], nums[l]
	l, r = l + 1, r - 1

Inspo: 189. Rotate Array

10 Inheritance

10.1 Syntax

The subclass use super().__init__() to inherit __init__() method from the superclass. Here is an example for how it works.

class Person:
	def __init__(self, name):
    	self.name = name

class Male(Person): # Male is the subclass, Person is its superclass
	def __init__(self, name):
    	# Person.__init__(self, name)
    	# super().__init__(name)
    	super(Male, self).__init__(name)
    	self.gender = "male"
  • super(Male, self).__init__(name) is equivalent to super().__init__(name) and Person.__init__(self, name).
  • Note, super() which has no argument presents super(subclass, self) by default.

Citation: 【python】B站最细致的super()详解,一定有你不知道的知识!

10.2 Example

from objprint import op

class Person:
	def __init__(self, name):
    	self.name = name

class Male(Person):
	def __init__(self, name):
    	# Person.__init__(self, name)
    	# super().__init__(name)
    	super(Male, self).__init__(name)
    	self.gender = "male"

m = Male("Frank")
op(m)

# Output
'''
<Male 0x7ff4b0196130
  .gender = 'male',
  .name = 'Frank'
>
'''
from objprint import op

class Animal:
    def __init__(self, age):
        self.age = age

class Person(Animal):
    def __init__(self, age, name):
        # super().__init__(age)
        super(Person, self).__init__(age)
        self.name = name

class Male(Person):
    def __init__(self, age, name, gender):
        # super().__init__(age, name)
        super(Male, self).__init__(age, name)
        self.gender = gender

m = Male(32, "Frank", "male")
op(m)

# Output
'''
<Male 0x7faa8803fe80
  .age = 32,
  .gender = 'male',
  .name = 'Frank'
>
'''

11 *args **kwargs

*args and **kwargs in Python | geeksforgeeks

  • *args receives arguments as a tuple.
  • **kwargs receives arguments as a dictionary.

Example 1: using Python *args

class car():
    def __init__(self, *args):
        self.speed = args[0]
        self.color = args[1]

audi = car(200, 'red')
bmw = car(250, 'black')
mb = car(190, 'white')

print(audi.color) # red
print(bmw.speed) # 250

Example 2: using Python **kwargs

class car():
	def __init__(self, **kwargs):
		self.speed = kwargs['s']
		self.color = kwargs['c']

audi = car(s=200, c='red')
bmw = car(s=250, c='black')
mb = car(s=190, c='white')

print(audi.color) # red
print(bmw.speed) # 250

12 Decorator

装饰器是在不修改目标函数代码的前提下,为目标函数新增功能的函数

import time
def timer(function):
    def wrapper(*args, **kwargs):
        time_start = time.time()
        function(*args, **kwargs)
        time_end = time.time()
        cost_time = time_end - time_start
        print(cost_time)
    return wrapper

@timer
def func1():
    print('func1')

@timer
def func2():
    print('func2')

@timer
def func3():
    print('func3')


if __name__ == '__main__':
    func1()
    func2()
    func3()

Example 1: Custom Initialization Logic

from abc import ABC, abstractmethod

class Base(ABC):
    def __init__(self, name, price):
        self._name = name
        self._price = price
        
    @property
    def name(self) -> str:
        return self._name
    
    @name.setter
    def name(self, name):
        self._name = name
        
    @property
    def price(self) -> str:
        return self._price
    
    @staticmethod
    def description():
        return "This is a base class for products"
    
    @classmethod
    def create_with_discount(cls, name, price, discount):
        discounted_price = price - (price * discount)
        return cls(name, discounted_price)
    
    @abstractmethod
    def load_data(self):
        pass

# Example subclass
class Product(Base):
    def load_data(self):
        print(f"Loading data for {self.name} with price {self._price}")


if __name__ == '__main__': 
    # Create an instance of Product with a discount
    product = Product.create_with_discount("Sample Product", 100.0, 0.1)
    print(product.name)
    print(product.price)  # Output will be 90.0 after applying 10% discount
    product.load_data()
    print(Product.description())

# Output:
"""
    Sample Product
    90.0
    Loading data for Sample Product with price 90.0
    This is a base class for products
"""
  • The @abstractmethod is used as a decorator to indicate that the load_data method is an abstract method that must be implemented by any subclass of the containing class. It is overridden in subclasses, ensuring that they provide their own implementation of this method.
  • The pass statement is used as a placeholder for future code. When the pass statement is executed, nothing happens, but you avoid getting an error when empty code is not allowed

Example 2: Factory Methods for Subclass Instances
When you have multiple subclasses and you want to create instances of the correct subclass based on some criteria:

class FoodProduct(Product):
    def load_data(self):
        print(f"Loading data for food product {self.name} with price {self._price}")

class ElectronicProduct(Product):
    def load_data(self):
        print(f"Loading data for electronic product {self.name} with price {self._price}")

class ClothingProduct(Product):
    def load_data(self):
        print(f"Loading data for clothing product {self.name} with price {self._price}")

class ProductFactory:
    @staticmethod
    def create_product(category, name, price):
        if category == "food":
            return FoodProduct(name, price)
        elif category == "electronics":
            return ElectronicProduct(name, price)
        elif category == "clothing":
            return ClothingProduct(name, price)
        else:
            raise ValueError(f"Unknown category: {category}")

# Create different types of products
food_product = ProductFactory.create_product("food", "Apple", 1.0)
electronics_product = ProductFactory.create_product("electronics", "Laptop", 999.99)
clothing_product = ProductFactory.create_product("clothing", "T-Shirt", 19.99)

food_product.load_data()
electronics_product.load_data()
clothing_product.load_data()

13 async I/O

老张爱喝茶,废话不说,煮开水。
出场人物:老张,水壶两把(普通水壶和响水壶)。

大白话 老张的反思
同步阻塞 老张把普通水壶放到火上,立等水开 老张觉得自己有点傻
同步非阻塞 老张把普通水壶放到火上,去客厅看电视,时不时去厨房看看水开没有。 老张还是觉得自己有点傻,于是变高端了,买了把会响笛的那种水壶。水开之后,能大声发出嘀~~~~的噪音
异步阻塞 老张把响水壶放到火上,立等水开。 老张觉得这样傻等意义不大
异步非阻塞 老张把响水壶放到火上,去客厅看电视,水壶响之前不再去看它了,响了再去拿壶。

所谓同步异步,只是对于水壶而言。 普通水壶,同步;响水壶,异步。 虽然都能干活,但响水壶可以在自己完工之后,提示老张水开了。这是普通水壶所不能及的。 同步只能让调用者去轮询自己(情况2中),造成老张效率的低下。

所谓阻塞非阻塞,仅仅对于老张而言。 立等的老张,阻塞;看电视的老张,非阻塞。 情况1和情况3中老张就是阻塞的,媳妇喊他都不知道。虽然3中响水壶是异步的,可对于立等的老张没有太大的意义。所以一般异步是配合非阻塞使用的,这样才能发挥异步的效用。

async
await:移动到其他coroutine object

import asyncio

async def main():
# A coroutine object, not function. If you call the function, it will not execute directly.
async def main():
	response = await 
	
import asyncio

async def count():
    print("One")
    await asyncio.sleep(1) # mimic the process of the I/O blocking
    print("Two")

async def main():
    await asyncio.gather(count(), count(), count()) # three tasks

if __name__ == "__main__":
    import time
    s = time.perf_counter()
    asyncio.run(main())
    elapsed = time.perf_counter() - s
    print(f"{__file__} executed in {elapsed:0.2f} seconds.")
One
One
One
Two
Two
Two
countasync.py executed in 1.01 seconds.

14 os

import os

print(__file__) # current executed relative file path 
print(os.path.abspath(__file__)) # current executed abstract file path
print(os.path.dirname(__file__)) # parent file path
print(os.path.dirname(os.path.dirname(__file__))) # parent of parent file path
print(os.path.join(os.path.dirname(os.path.dirname(__file__)), "knowledge_base"))

KB_ROOT_PATH = os.path.join(os.path.dirname(__file__), "knowledge_base")
if not os.path.exists(KB_ROOT_PATH):
    os.mkdir('knowledge_base')
posted @ 2023-05-31 15:42  ForHHeart  阅读(37)  评论(0编辑  收藏  举报