[Python] 00 - Books & tutorial
A.I. & Optimization
Advanced Machine Learning, Data Mining, and Online Advertising Services
Ref: Top 25 Python Programming Books
Ref: 廖雪峰的python教程
Ref: https://repl.it/languages/python3【在线编译调试python】
Ref: 花了三个月终于把所有的Python库全部整理了【比较全,有价值】
免费视频教程
一、工程夯实策略
基础
进阶
高性能
二、自我评估
Ref: How to Hire Python Developers and Identify True Masters
/* implement */
面试问题收集
None类型
(1) 空类型的“否“ 即是None
空列表,空元组,空字典前面加not 都是None。
(2) None是全局的一个特殊的类型。
>>> type(None) <class 'NoneType'> >>> a=None >>> b=None >>> id(a)==id(b) True
is 对比 ==
== None时,调用了eq。
>>> class test(): ... def __eq__(self,other): ... return True ...
>>> t = test() >>> t is None False >>> t == None True
陷阱:空List参数
默认参数很有用,但使用不当,也会掉坑里。默认参数有个最大的坑,演示如下:
-
- 当你使用默认参数调用时,一开始结果也是对的;
- 但是,再次调用
add_end()
时,结果就不对了。
def add_end(L=[]):
print('L = ' L) L.append('END') return L add_end() add_end()
Output:
>>> add_end()
L = []
['END']
>>> add_end()
L = ['END']
['END', 'END']
原因解释如下:
Python函数在定义的时候,默认参数L
的值就被计算出来了,即[]。
因为默认参数L
也是一个变量,它指向对象[]。
每次调用该函数,如果改变了L
的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的[]
了。
简单的说就是,函数定义后,默认参数类似于一个static变量。
陷阱:Closure的内部变量
def count(): fs = [] for i in range(1, 4): def f(): return i*i # 问题所在:返回的该函数的i,却不属于自己 fs.append(f) return fs
f1, f2, f3 = count()
print(f1())
print(f2())
print(f3())
-------
Output:
-------
9
9
9
解决方案:如果一定要引用循环变量怎么办?方法是再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改,已绑定到函数参数的值不变:
def count(): def f(j): # 因为经过了函数的封装,所以保持了函数内部变量的独立性 def g(): return j*j return g fs = [] for i in range(1, 4): fs.append(f(i)) # f(i)立刻被执行,因此i的当前值被传入f() return fs f1, f2, f3 = count()
偏函数
简单总结functools.partial
的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。
固定子函数的某些参数
>>> import functools >>> int2 = functools.partial(int, base=2) # 固定了参数base=2
>>> int2('1000000') 64 >>> int2('1010101') 85
作为List 参数的默认元素
max2 = functools.partial(max, 10) max2(5, 6, 7) # 相当于 args = (10, 5, 6, 7) max(*args)
与c++对比
字典,元素统计
Python:
def get_counts(sequence):
counts = {}
for x in sequence:
if x in counts:
counts[x] += 1
else:
counts[x] = 1
return counts
c++:map切记元素为空时的陷阱
#include <iostream>
#include <map>
using namespace std;
int main()
{
cout << "Hello World!" << endl;
map<string, int> m;
cout << m.size() << endl;
m.insert(std::pair<string,int>("a",100));
cout << m.size() << endl;
return 0;
}
字典,元素有么?
Python:in & not in
>>> 'a' in count
True
>>> 'a' not in count
False
C++:
iter = m.find(key);
if(iter!=m.end())
{
return iter->second;
}
return null;
排序
C++ sort:
Goto: [c++] Associative Containers
Python sort:
如果是自定义排序呢?
python 字典(dict)的特点就是无序的,按照键(key)来提取相应值(value),
如果我们需要字典按值排序的话,那可以用下面的方法来进行:
(1) 按照value从大到小排序:
dic = {'a':31, 'bc':5, 'c':3, 'asd':4, 'aa':74, 'd':0} # dic.iteritems() 得到[(键,值)]的列表。 # 然后用sorted方法,通过key这个参数,指定排序是按照value,也就是第2个元素d[1]的值来排序。
# reverse = True表示是需要翻转的,默认是从小到大,翻转的话,那就是从大到小。 dict= sorted(dic.iteritems(), key=lambda d:d[1], reverse = True) print dict
(2) 对字典按键(key)排序:
dic = {'a':31, 'bc':5, 'c':3, 'asd':4, 'aa':74, 'd':0} dict= sorted(dic.iteritems(), key=lambda d:d[0]) # 按照第2个元素d[1]的值来排序 print dict
*(3) 遍历则使用:
for (current_state, current_position) in transitions:
# print(current_state, tape[current_position])
new_state, new_bit, direction = transitions[current_state, current_position]
current_state = new_state
tape[current_position] = new_bit
if direction == 'R':
current_position += 1
else:
current_position -= 1
print(tape)
字符串,分割
python :
file = open('multiplication.txt', 'r')
program = file.readlines()
#print(program)
instructions = [line.split() for line in program if not line.startswith('#')] # filter method
#print(instructions)
#for instruction in instructions:
# print(instruction)
transitions = {}
### 1 2 3 4 5
### state, bit, new_state, new_bit, direction
for state, bit, new_state, new_bit, direction in instructions:
print(state, bit, new_state, new_bit, direction)
transitions[state, int(bit) ] = new_state, int(new_bit), direction
### 字典存储好数据,然后打印出来瞧上一瞧
print(transitions)
C++ : http://www.cplusplus.com/faq/sequences/strings/split/ 专题
The reality is that there are so many ways to split strings it is overwhelming. Here are some, in no particular order, with examples:
Method |
Iterated or all-at-once |
Delimiter |
Empty Fields | ||||||
---|---|---|---|---|---|---|---|---|---|
char |
string |
function |
quotable |
offset |
no case |
elided |
trailing | ||
Boost String Algorithms: Split | all-at-once | Y | Y | Y | 4 | Y | |||
Boost String Algorithms: Split Regex | all-at-once | 1 | Y | regex | 2 | 2 | 2 | ? | |
Boost Tokenizer | iterated3 | Y | Y | Y | Y | opt | Y | ||
Trolltech Qt’s QString::split() |
all-at-once | Y | Y | regex | 2 | Y | opt | Y | |
GNU String Utility Functions: Split | all-at-once | 1 | Y | Y | |||||
iostreams and getline() |
iterated3 | Y | Y | Y | |||||
string::find_first_of() |
all-at-once3 | Y | Y | Y | |||||
strtok() |
iterated3 | 1 | Y | always | NO | ||||
Roll your own C tokenizer | iterated3 | 1 | Y | opt | Y |
#include <boost/algorithm/string.hpp>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
using namespace boost;
void print( vector <string> & v )
{
for (size_t n = 0; n < v.size(); n++)
cout << "\"" << v[n] << "\"\n";
cout << endl;
}
int main()
{
string s = "a,b, c ,,e,f,";
vector <string> fields;
cout << "Original = \"" << s << "\"\n\n";
cout << "Split on \',\' only\n";
split( fields, s, is_any_of( "," ) );
print( fields );
cout << "Split on \" ,\"\n";
split( fields, s, is_any_of( " ," ) );
print( fields );
cout << "Split on \" ,\" and elide delimiters\n";
split( fields, s, is_any_of( " ," ), token_compress_on ); // <---- best
print( fields );
return 0;
}
Original = "a,b, c ,,e,f," Split on ',' only "a" "b" " c " "" "e" "f" "" Split on " ," "a" "b" "" "c" "" "" "e" "f" "" Split on " ," and elide delimiters "a" "b" "c" "e" "f" ""
End.