-
Notifications
You must be signed in to change notification settings - Fork 0
/
PYTHON_STUDY
147 lines (125 loc) · 6.02 KB
/
PYTHON_STUDY
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
python knowledge:
1 how to sort with multiple keys:
data.sort(key=lambda item: (item[1], item[0]), reverse=True)
here, item[1] is the primary key and item[0] is the secondary key
if we want to sort keys in different directions(increasing/decreasing) we can just use negative, like
data.sort(key=lambda item: (item[1], 0-item[0]), reverse=True) we sort item[1] in increasing and item[0] in decreasing if ties occur
2 ordereddict:
if raw_key not in self.hashtable.keys():
self.hashtable[raw_key] = collections.OrderedDict() #we use ordereddict structure to store column key-value
self.hashtable[raw_key][column_key] = column_value
here we use ordereddict to store column_key and column_value pair, using ordereddict can make us easy to return output in order!!!
we can just do sth like: new_hash = collections.OrderedDict(sorted(self.hashtable[key].items())) where we can traverse new_hash
in order and output in order !!!
we can also sort values/keys in ordereddict:
>>> a
OrderedDict([(2, [3, 0]), (4, [3, 1]), (1, [1, 2])])
we show how to sort the first element of value as the primary key and the second element of value will be the secondary key
>>> a=collections.OrderedDict(sorted(a.items(),key=lambda item:(item[1][0],item[1][1]),reverse=True))
>>> a
OrderedDict([(4, [3, 1]), (2, [3, 0]), (1, [1, 2])])
how to sort their key:
a=collections.OrderedDict(sorted(a.items(),key=lambda item:item[0]))
how to sort their value(if value is not a list)
a=collections.OrderedDict(sorted(a.items(),key=lambda item:item[1]))
3 base convertion:
convert a string of char into a base 62 number:from higher bit to lower bit(left to right)
id = 0
for ch in string:
id = 62 * id + ord(ch)
convert a base 62 number into a string of char:from lower bit to higher bit(right to left)
while number > 0:
output_string = str(number%62) + output_string
number /= 62
4 while loop strick:
1) when perform binary search in a while loop:
mid = int((start+end)/2)
if we update left/right boundary, like start = mid + 1 or end = mid - 1 then the while condition is while start <= end;
if we update left/right boundary, like start = mid+1 or end = mid then the while condition is while start < end.
what we want to find is the biggest element that smaller than target, return start-1
ex:
To find the biggest element that less than target:
while start < end:
mid = int((start+end)/2)
if mid < target:
start = mid + 1
else:
end = mid
return start - 1
special note: returning start -1 means we cannot reach the end point and this means the end point is a maximum point that is
unreachable from start ! Therefore, we have to make our upperbound addition by 1 if our rightmost point is an reachable one !
if max is reachable from mid then we just need to let end = max+1 !!!
the reason we return start-1 because we interested in the biggest one that less than target !!!
Alternatively:
while start <= end:
mid = int((start+end)/2)
if mid < target:
start = mid + 1
else:
end = mid - 1
return start-1
Same is here, end have to be an reachable point! end = max + 1
Another equivalent form:
while start + 1 < end:
mid = start + (end-start)/2
if mid > target:
end = mid
else:
start = mid
return start
Attention: when construct an array, we rather use array[i] = xxx than array.append(xxx) because append operation will cost more
than directly assignment !!!
Defensive programming by using assertion:
example:
def daysBetweenDates(year1, month1, day1, year2, month2, day2):
"""Returns the number of days between year1/month1/day1
and year2/month2/day2. Assumes inputs are valid dates
in Gregorian calendar."""
# program defensively! Add an assertion if the input is not valid!
days = 0
assert dateIsBefore(year1, month1, day1, year2, month2, day2) == True
while dateIsBefore(year1, month1, day1, year2, month2, day2):
year1, month1, day1 = nextDay(year1, month1, day1)
days += 1
return days
def test():
test_cases = [((2012,9,30,2012,10,30),30),
((2012,1,1,2013,1,1),360),
((2012,9,1,2012,9,4),3),
((2013,1,1,1999,12,31), "AssertionError")]
for (args, answer) in test_cases:
try:
result = daysBetweenDates(*args)
if result != answer:
print "Test with data:", args, "failed"
else:
print "Test case passed!"
except AssertionError:
if answer == "AssertionError":
print "Nice job! Test case {0} correctly raises AssertionError!\n".format(args)
else:
print "Check your work! Test case {0} should not raise AssertionError!\n".format(args)
Performance comparision with list(), set() and dict():
1 Where an element is in a list definitely impacts how long it takes to discover that the element exists in the list!
Elements near the beginning of a list are found very quickly. Elements near the end of the list take longer.
2 When checking for membership of an element in a list, itt takes longer to figure out an element doesn't exist in
that list when the list is big.
The time it takes to test for membership in a list "scales linearly" with the size of the list.
That just means if you double the size of the list you double the amount of time it takes to test for membership of an
element (on average).
On the other sides, As you can see, the performance of sets and dictionaries does not depend on the size of the
set / dictionary and membership tests are consistently fast. Fast is good.
Introduction to name tuple:
# named tuple's need to be imported from the collections library
from collections import namedtuple
# here we define Point as a new type of thing.
# It has properties x and y.
Point = namedtuple("Point", ["x", "y"])
# here we actually instantiate a point
p1 = Point(5, -3)
print(p1)
print(p1.x,p1.y) or print(p1[0],p1[1])
Unpack arguments as input:
x(a,b,c)
we can define X as following:
def X(*inputs): #where '*input' means number of arguments can be arbitary number !