Hear i have a list, and i have to get duplicates from it. So i can use solution like this:
arr = [1, 1, 2, 3, 4, 4, 5]
def get_duplicates(arr):
duplicates = []
for index in range(len(arr)-1):
if arr[index] == arr[index+1]:
duplicates.append(arr[index])
return duplicates
print(*duplicates)
Ok, what if i have three or more duplicates in my list? I did something like that:
arr = [1, 1, 1, 2, 3, 4, 4, 4, 4, 5]
def get_duplicates(arr):
duplicates = []
for index in range(len(arr)-1):
if arr[index] == arr[index+1]:
duplicates.append(arr[index])
return duplicates
print(*set(duplicates))
Is that both my code works with O(n) or not? I just dont know what is speed of set() function in python, but i think that first for loop takes O(n),
if set() takes O(n), it doesnt matter, because finally i will have O(2n) = O(n) in this case.
Do i solve that task correctly, or my code is not effective? Smart people, help me please))
If u know how to do it in wright direction, explain me please.
Here is a version that is clearly O(n):
def get_duplicates(arr):
last_duplicate = None
duplicates = []
for i,v in enumerate(arr[1:]):
if v==arr[i-1] and v!=last_duplicate:
duplicates.append(v)
last_duplicate = v
return duplicates
Note that this assumes, as your original code does, that duplicates will be adjacent to one another. It also assumes that the first duplicate is not None.
My code looks like this :
input_list = [0,3,5,7,15]
def sample_fun(input_list):
for idx,ele in enumerate(input_list):
input_list = [x-2 for x in input_list if (x-2)>0]
print('Index:',idx,'element:',ele,'New list:',input_list)
sample_fun(input_list)
What I am trying to show is that the value of input_list that is used inside of enumerate keeps changing inside the for loop. I want the for loop to iterate through the new value of input_list. But it appears that the for loop iterates through the initial value of input_list even though I am changing it's values.
Index: 0 element: 0 New list: [1, 3, 5, 13]
Index: 1 element: 3 New list: [1, 3, 11]
Index: 2 element: 5 New list: [1, 9]
Index: 3 element: 7 New list: [7]
Index: 4 element: 15 New list: [5]
I understand that the for loop is iterating through the initial enumerate output.
Is there any way I could make the for loop iterate through the new values of input_list like:
In the first iteration when index: 0 and element:0, input_list = [1, 3, 8, 13]
In the next iteration, I want the values to be like this - index: 0 and element: 1 and input_list = [1, 3, 11]
In the next iteration, I want the values to be like this - index: 0 and element: 1, now since the element is same as previous element value, I would like to loop through to - index:1 and element : 3 and input_list = [1, 9]
I want the loop to behave in this way.
I want to loop through the changing values of the input_list.
I'm not sure how to do this. It would be great if anybody could help me out here. Thanks in advance!
In the for loop, you keep assigning to input_list a new list object:
input_list = [x-2 for x in input_list if (x-2)>0]
while the iterator of the for loop is based on the original list object, and it therefore would not reflect the new list objects assigned to input_list.
You can instead alter input_list in-place by slicing its entire range:
input_list[:] = [x-2 for x in input_list if (x-2)>0]
so that the iterator can reflect changes made to the same list object.
I'm trying to count the number of times a specific number appears in serval lists vertically.
My code:
import csv
with open('Superheroes.csv', 'r') as csvfile:
first_line = csvfile.readline()
super_reader = csv.reader(csvfile, delimiter=',')
result = []
for vote in super_reader:
vote.pop(0)
result.append([int(x) if x else 0 for x in vote])
result = [vote.count(1) for i in zip(*result)]
print(result)
example picture
So from the example picture, say I wanted to know how many times the number 11 appeared in every column of all the lists. I would expect an output of [0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 4, 2]
Thanks
You can use sum with a generator expression that outputs whether each item in a column matches the target number to perform the counting after transposing the rows into columns with zip:
def count(rows, num):
return [sum(i == num for i in map(int, col)) for col in zip(*rows)]
so that given the content of test.csv as follows:
2,1,3
3,2,1
1,3,3
1,3,2
count(csv.reader(open('test.csv')), 3) would return:
[1, 2, 2]
Demo: https://repl.it/#blhsing/IllAffectionateQuarks#main.py
if I have a dictionary
x ={0: 0, 1: 4, 2: 0, 3: 2, 4: 2, 5: 4}
how do i get the keys of all the largest values
In this case they would be 1 and 5 .
Not a duplicate question. looking to find all the keys and not just the one.
x ={0: 0, 1: 4, 2: 0, 3: 2, 4: 2, 5: 4}
maximum = max(x.values())
keys = [key for key, value in x.items() if value == maximum]
print(keys) # => [1, 5]
There is a class in collections called Counter that does exactly what you want. It provides the exact functionality you require via it's most_common method:
from collections import counter
maxes = Counter(x).most_common(2)
print([x[0] for x in maxes])
[1, 5]
Now this is probably not exactly what you want because I hard coded in the number 2. You can get this by using another Counter on the values of your dictionary!
x = Counter(x) # This preserves x: just makes it a subclass of dict
max_count = Counter(x.values())[x.most_common(1)[0][1]]
maxes = x.most_common(max_count)
maxes = [x[0] for x in maxes]
Here, I compute the number of times that the most common value occurs by counting all the different values, and then checking the maximum one using x.most_common(1)[0][1].
Please do not select this answer. #BrightOne has the right answer. This is just a thing I did to see if I could avoid using anything but Counters. It is not actually a good idea.
I am suppose to put a group of people (given at run-time) in to a 2 dimensional array of spot, group together in a row randomly(find out all possible positions and randomly pick one)
To start of, I wanna try in an array first
if I have an array of spots of size 10 like below
spots[occupied,open,open,occupied,occupied,occupied,open,open,open,open]
to put 2 people
Is there a particular algorithm to do this kind of problem?
Thanks for any help!
in python:
seats =["occupied","open","open","occupied","occupied","occupied","open","open","open","open"]
def empty(seats,index,count):
if count == 0:
return True
else:
return (seats[index] == "open") & empty(seats,index+1,count-1)
def findEmpty(seats,count):
result = []
for (i=0;i<seats.size-count+1,i++)
if empty(seats,i,count):
result.append(<list of consecutive numbers from i to i+count>)
return result
print findEmpty(seats,2)
>>>[[1, 2], [6, 7], [7, 8], [8, 9]]
here's another approach, its a little more efficient:
seats = ["occupied","open","open","occupied","occupied","occupied","open","open","open","open"]
//counts the number of consecutive free seats starting at position index
def countEmpty(seats,index):
if index >= len(seats) or seats[index] == "occupied":
return 0
return 1 + countEmpty(seats,index+1)
def findEmpty(seats,count):
result = []
i = 0
while i < len(seats)-count+1:
c = countEmpty(seats,i)
if c>=count:
for (j=i;j<i+c-count+1;j++):
result.append(<list of consecutive numbers from j to j+count>)
i += 1 + c
return result
print findEmpty(seats,2)
>>>[[1, 2], [6, 7], [7, 8], [8, 9]]
and finally, if you did choose to use python you could do it in one line:
seats =["occupied","open","open","occupied","occupied","occupied","open","open","open","open"]
count = 2
print [range(i,i+count) for i in range(len(seats)-count+1) if all([seats[j]=="open" for j in range(i,i+count)]) ]
>>> [[1, 2], [6, 7], [7, 8], [8, 9]]
Pseudo code:
//Create 2 lists of blocks, both empty: tmp and final
List tmp=new List;
List final=new List;
//Cycle the seats
for (int i=0;i<length(seats);i++) {
//If the seat is occupied, start over
if (seats[i]==occupied) tmp.empty();
else {
//Cycle existing block candidates, add free seat
foreach (ref block in tmp) {
block.add(seats[i])
if (length(block)>=people_count) {
//HEUREKA, got a fitting block: Move it to the final list
tmp.remove(block)
final.add(block)
}
}
//Start a new block with this seat
tmp.add(new block(seats[i]));
//Read below for this edge case
}
}
final now has the blocks.
If you allow the edge case of people_num being 1, you have to check for a complete block at the position indicated in the pseudocode
I shall use Mathematica code but I believe you can follow the logic.
Starting with:
dat = spots[occupied, open, open, occupied, occupied, occupied, open, open, open, open];
fill = {"Alpha", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot"};
First find a random permutation of the list fill (it is easy to find an algorithm on StackOverflow):
randomfill = RandomSample # fill
{"Delta", "Echo", "Alpha", "Bravo", "Charlie", "Foxtrot"}
Then "map" a function onto each element of the spots list, and if the element is open return the next value from the randomfill list, else return the element unchanged:
i = 1;
If[# === open, randomfill[[i++]], #] & /# dat
spots[occupied, "Delta", "Echo", occupied, occupied, occupied, "Alpha", "Bravo", "Charlie", "Foxtrot"]