Related
I Would like to find Mode in python array or list, but if all numbers appears at only once(or we can say there is no Mode) I wanted to print smallest number.
n_num = [64630, 11735, 14216, 99233, 14470, 4978, 73429, 38120, 51135, 67060]
from statistics import mode
def mode(n_num):
n_num.sort()
m = min(n_num)
return m
print(str(mode(n_num)))
You can use multimode() from the statistics package instead of mode(). This will return multiple values when there is more than one mode to choose from. You can take the min() from that:
from statistics import multimode
n_num = [10, 9, 1, 2, 3, 4]
min(multimode(n_num))
# 1
n_num = [10, 9, 1, 2, 3, 4, 9, 10 ]
min(multimode(n_num))
#9
[Note: this requires python 3.8]
try to use the try statement
import statistics
def special_mode(iterable):
try:
result = statistics.mode(iterable)
except statistics.StatisticsError: # if mode() fail, it do min()
result = min(iterable)
return result
mylist = [0, 1, 6, 9, 1, -7]
print(special_mode(mylist))
# return the 1 because of the mode function
mylist = [0, 1, 6, 9, -7]
print(special_mode(mylist))
# return the -7 beacuse it's the smallest
hope it was helpful
Python already has a min and max function built-in to find the smallest and largest values in a list
n = [64630, 11735, 14216, 99233, 14470, 4978, 73429, 38120, 51135, 67060]
smallest_number = min(n)
largest_number = max(n)
I have this question for quit a while and would like to make sure that I understand it correctly. I am now working on a question on algorithm
Kth Largest Number in a Stream
Design a class to efficiently find the Kth largest element in a stream of numbers.
The class should have the following two things:
The constructor of the class should accept an integer array containing initial numbers from the stream and an integer K.
The class should expose a function add(int num) which will store the given number and return the Kth largest number.
The result is:
from heapq import *
class KthLargestNumberInStream:
# minHeap = []
def __init__(self, _input, _k):
self.k = _k
# the update minHeap will keep in the class and won't get cleared
self.minHeap = []
# rather than assigning values to input
# call the add function to add
for num in _input:
self.add(num)
def add(self, num):
# minHeap is defined outside this function and within the class
# need to use the self.minHeap to call it
heappush(self.minHeap, num)
# return the top k
if len(self.minHeap) > self.k:
heappop(self.minHeap)
# print(self.minHeap)
return self.minHeap[0]
def main():
kthLargestNumber = KthLargestNumberInStream([3, 1, 5, 12, 2, 11], 4)
print("4th largest number is: " + str(kthLargestNumber.add(6)))
print("4th largest number is: " + str(kthLargestNumber.add(13)))
print("4th largest number is: " + str(kthLargestNumber.add(4)))
main()
The print out the all the elements visited in the min heap is as:
[3]
[1, 3]
[1, 3, 5]
[1, 3, 5, 12]
[1, 2, 5, 12, 3]
[1, 2, 5, 12, 3, 11]
[1, 2, 5, 12, 3, 11, 6]
4th largest number is: 1
[1, 2, 5, 12, 3, 11, 6, 13]
4th largest number is: 1
[1, 2, 5, 4, 3, 11, 6, 13, 12]
4th largest number is: 1
I am curious that each time we called the kthLargestNumber = KthLargestNumberInStream([3, 1, 5, 12, 2, 11], 4), and why it won't create a new and empty heap and then add values to it, but keep the element from the previous call of the add function.
However, in this question Anther question, the max_sum will get reset each time.
Thanks for your help in advance.
I want to print the top 10 distinct elements from a list:
top=10
test=[1,1,1,2,3,4,5,6,7,8,9,10,11,12,13]
for i in range(0,top):
if test[i]==1:
top=top+1
else:
print(test[i])
It is printing:
2,3,4,5,6,7,8
I am expecting:
2,3,4,5,6,7,8,9,10,11
What I am missing?
Using numpy
import numpy as np
top=10
test=[1,1,1,2,3,4,5,6,7,8,9,10,11,12,13]
test=np.unique(np.array(test))
test[test!=1][:top]
Output
array([ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
Since you code only executes the loop for 10 times and the first 3 are used to ignore 1, so only the following 3 is printed, which is exactly happened here.
If you want to print the top 10 distinct value, I recommand you to do this:
# The code of unique is taken from [remove duplicates in list](https://stackoverflow.com/questions/7961363/removing-duplicates-in-lists)
def unique(l):
return list(set(l))
def print_top_unique(List, top):
ulist = unique(List)
for i in range(0, top):
print(ulist[i])
print_top_unique([1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], 10)
My Solution
test = [1,1,1,2,3,4,5,6,7,8,9,10,11,12,13]
uniqueList = [num for num in set(test)] #creates a list of unique characters [1,2,3,4,5,6,7,8,9,10,11,12,13]
for num in range(0,11):
if uniqueList[num] != 1: #skips one, since you wanted to start with two
print(uniqueList[num])
I'm traversing a two-dimensional list (my representation of a matrix) in an unusual order: counterclockwise around the outside starting with the top-left element.
I need to do this more than once, but each time I do it, I'd like to do something different with the values I encounter. The first time, I want to note down the values so that I can modify them. (I can't modify them in place.) The second time, I want to traverse the outside of the matrix and modify the values of the matrix as I go, perhaps getting my new values from some generator.
Is there a way I can abstract this traversal to a function and still achieve my goals? I was thinking that this traverse-edge function could take a function and a matrix and apply the function to each element on the edge of the matrix. However, the problems with this are two-fold. If I do this, I don't think I can modify the matrix that's given as an argument, and I can't yield the values one by one because yield isn't a function.
Edit: I want to rotate a matrix counterclockwise (not 90 degrees) where one rotation moves, for example, the top-left element down one spot. To accomplish this, I'm rotating one "level" (or shell) of the matrix at a time. So if I'm rotating the outermost level, I want to traverse it once to build a list which I can shift to the left, then I want to traverse the outermost level again to assign it those new values which I calculated.
Just create 4 loops, one for each side of the array, that counts through the values of the index that changes for that side. For example, the first side, whose x index is always 0, could vary the y from 0 to n-2 (from the top-left corner to just shy of the bottom-left); repeat for the other sides.
I think there are two approaches you can take to solving your problem.
The first option is to create a function that returns an iterable of indexes into the matrix. Then you'd write your various passes over the matrix with for loops:
for i, j in matrix_border_index_gen(len(matrix), len(matrix[0])): # pass in dimensions
# do something with matrix[i][j]
The other option is to write a function that works more like map that applies a given function to each appropriate value of the matrix in turn. If you sometimes need to replace the current values with new ones, I'd suggest doing that all the time (the times when you don't want to replace the value, you can just have your function return the previous value):
def func(value):
# do stuff with value from matrix
return new_value # new_value can be the same value, if you don't want to change it
matrix_border_map(func, matrix) # replace each value on border of matrix with func(value)
I have added a few lines of python 3 code here. It has the mirror function and a spiral iterator (not sure, if that's what you meant). No doc strings (sorry). It is readable though. Change print statement for python 2.
EDIT : FIXED A BUG
class Matrix():
def __init__(self, rows=5, cols=5):
self.cells = [[None for c in range(cols)] for r in range(rows)]
def transpose(self):
self.cells = list(map(list, zip(*self.cells)))
def mirror(self):
for row in self.cells:
row.reverse()
def invert(self):
self.cells.reverse()
def rotate(self, clockwise=True):
self.transpose()
self.mirror() if clockwise else self.invert()
def iter_spiral(self, grid=None):
grid = grid or self.cells
next_grid = []
for cell in reversed(grid[0]):
yield cell
for row in grid[1:-1]:
yield row[0]
next_grid.append(row[1:-1])
if len(grid) > 1:
for cell in grid[-1]:
yield cell
for row in reversed(grid[1:-1]):
yield row[-1]
if next_grid:
for cell in self.iter_spiral(grid=next_grid):
yield cell
def show(self):
for row in self.cells:
print(row)
def test_matrix():
m = Matrix()
m.cells = [[1,2,3,4],
[5,6,7,8],
[9,10,11,12],
[13,14,15,16]]
print("We expect the spiral to be:", "4, 3, 2, 1, 5, 9, 13, 14, 15, 16, 12, 8, 7, 6, 10, 11", sep='\n')
print("What the iterator yields:")
for cell in m.iter_spiral():
print(cell, end=', ')
print("\nThe matrix looks like this:")
m.show()
print("Now this is how it looks rotated 90 deg clockwise")
m.rotate()
m.show()
print("Now we'll rotate it back")
m.rotate(clockwise=False)
m.show()
print("Now we'll transpose it")
m.transpose()
m.show()
print("Inverting the above")
m.invert()
m.show()
print("Mirroring the above")
m.mirror()
m.show()
if __name__ == '__main__':
test_matrix()
This is the output:
We expect the spiral to be:
4, 3, 2, 1, 5, 9, 13, 14, 15, 16, 12, 8, 7, 6, 10, 11
What the iterator yields:
4, 3, 2, 1, 5, 9, 13, 14, 15, 16, 12, 8, 7, 6, 10, 11,
The matrix looks like this:
[1, 2, 3, 4]
[5, 6, 7, 8]
[9, 10, 11, 12]
[13, 14, 15, 16]
Now this is how it looks rotated 90 deg clockwise
[13, 9, 5, 1]
[14, 10, 6, 2]
[15, 11, 7, 3]
[16, 12, 8, 4]
Now we'll rotate it back
[1, 2, 3, 4]
[5, 6, 7, 8]
[9, 10, 11, 12]
[13, 14, 15, 16]
Now we'll transpose it
[1, 5, 9, 13]
[2, 6, 10, 14]
[3, 7, 11, 15]
[4, 8, 12, 16]
Inverting the above
[4, 8, 12, 16]
[3, 7, 11, 15]
[2, 6, 10, 14]
[1, 5, 9, 13]
Mirroring the above
[16, 12, 8, 4]
[15, 11, 7, 3]
[14, 10, 6, 2]
[13, 9, 5, 1]
I would go with generator functions. They can be used to create iterators over which we can iterate. An Example of a generator function -
def genfunc():
i = 0
while i < 10:
yield i
i = i + 1
>>> for x in genfunc():
... print(x)
...
0
1
2
3
4
5
6
7
8
9
When calling the generator function, it returns a generator object -
>>> genfunc()
<generator object genfunc at 0x00553AD0>
It does not start going over the function at that point. When you start iterating over the generator object, calling for its first element, it starts going over the function, untill it reaches the first yield statement, and at that point it returns the value (in above case, it returns value of i) . And it also saves the state of the function at that point (that is it saves at what point the execution was when the value was yielded, what were the values for the variables in the local namespace, etc).
Then when it tries to get the next value, again execution starts from where it stopped last time, till it again yield another value. And this continues on.
I have a list defined as:
pad = [unhexlify('00' * (16-j) + ('%02d' % j) * j) for j in range(1, 17)]
This constructs a pad list for a padding oracle attack. Due to how this attack works I need to cycle through elements 2-16, then if I don't get a hit go back and try the 1st element. Here is the loop:
for padsel in pad: #increment pad
print(str(hexlify(padsel)) + "- selected pad")
for i in range(256): #increment guess
g = unhexlify("000000000000000000000000000000" + "{:02x}".format(i))
print(str(hexlify(g)) + "- guess")
if attack(g,padsel,ct_prev, ct_target):
m2 += "{:02x}".format(i)
print(m2)
break
else:
continue
m2 = m2[::-1]
print(m2 + "- m2")
How do I change the outer loop definition to do this?
Pseudo code:
for padsel in pad (items 2-16):
do stuff until hitting a break condition
else:
do stuff on element 1
Thanks.
Rather than use an else clause on the for loop, just modify the iterable (list) that you iterate over:
for padsel in (pad[1:16] + [pad[0]]):
print(str(hexlify(padsel)) + "- selected pad")
for i in range(256): #increment guess
g = unhexlify("000000000000000000000000000000" + "{:02x}".format(i))
print(str(hexlify(g)) + "- guess")
if attack(g,padsel,ct_prev, ct_target):
m2 += "{:02x}".format(i)
print(m2)
break
else:
continue
m2 = m2[::-1]
print(m2 + "- m2")
Using an else clause would require duplication of the code in the body of the for loop, or refactoring the body into a function so that duplication is not required. But, since the first item is processed in the same way as the other items, the simplest way is to organise for it to be processed last by iterating over items 2 through 16 and then item 1 if required.
>>> l = range(1,16+1)
>>> print l
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
>>> print l[1:16] + [l[0]]
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1]
The last statement effectively moved the first element of the list to the end of the list. If you don't mind if the list is modified, or even prefer it, you can do this:
>>> l = range(1,16+1)
>>> l.append(l.pop(0))
>>> print l
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1]
If you need to keep original list untouched, try:
for item in items[1:16]: # iterate through elements 1-17 (list indexes starts at 0
do stuff
if condition:
break
else: # else in for loops will be run if loop ended normally (w/o `break`)
do stuff with items[0]
Keep in mind, that slicing lists (list[x:y]) will create a copy of existing list. This can become a memory issue, when used with huge lists.