I am dealing with a problem where I need to keep track of the minimum number in a list. However, this list is constantly diminishing, say like from a million elements to a single element. I was looking for a way to avoid checking the minimum value everytime I got a one element smaller list. Like keeping track of the minimum element and if it is removed the next minimum becomes the minimum. I want to accomplish this in linear time.(It should be achievable given the mechanics of the problem)
What I thought of since I started that, I can use collections Counter to count elements in the list. Then I find the minimum(already O(2*n)), and everytime I remove an element, I subtract 1 from the value of the dictionary key. However when the minimum number's count is depleted, I would still require to find the second minimum element so it could replace it.
Please help me find a solution to this. I would say this is an interesting problem.
Let's say your program would take some time to sort that list
a = [10,9,10,8,7,6,5,4,3,2,1,1,1,0] # you're just removing
a = sorted(a) #sort ascending
# then you remove stuff from your list
# but always a[0] is minimum element
min = a[0] #you must be careful, there must be at least one item so check that before
#getting the min
So there is no need for searching it every time
Related
I'm currently using Counter() method for this. But the issue I'm facing is that when there are multiple elements with same number of values I'm getting the out of key value of number which occurs first in the list.
a=[1,3,2,2,3]
coun=Counter(a)
print(coun.most_common(1))
Output: [(3,2)]
a=[1,2,3,2,3]
coun=Counter(a)
print(coun.most_common(1))
Output: [(2,2)]
I want to get the key value which is lower instead of the one that occurs first i.e 2 here irrespective of the order. I could sort the list but I'm considering that sorting can use up a lot of time.
Please help
Sorry for the formatting mess.
Depending on the amount of duplicates you are expecting you could simply check more of the most_common values? Assuming that there's no more than 100 values with exactly the same amount you could simply do:
print(sorted(coun.most_common(100))[0])
You could use a different values for 100 of course. But now the list to sort would be at most 100 tuples, which of course isn't a problem.
I have n lists each of length m. assume n*m is even. i want to get a randomly shuffled list with all elements, under the constraint that the elements in locations i,i+1 where i=0,2,...,n*m-2 never come from the same list. edit: other than this constraint i do not want to bias the distribution of random lists. that is, the solution should be equivalent to a complete random choice that is reshuffled until the constraint hold.
example:
list1: a1,a2
list2: b1,b2
list3: c1,c2
allowed: b1,c1,c2,a2,a1,b2
disallowed: b1,c1,c2,b2,a1,a2
A possible solution is to think of your number set as n chunks of item, each chunk having the length of m. If you randomly select for each chunk exactly one item from each lists, then you will never hit dead ends. Just make sure that the first item in each chunk (except the first chunk) will be of different list than the last element of the previous chunk.
You can also iteratively randomize numbers, always making sure you pick from a different list than the previous number, but then you can hit some dead ends.
Finally, another possible solution is to randomize a number on each position sequentially, but only from those which "can be put there", that is, if you put a number, none of the constraints will be violated, that is, you will have at least a possible solution.
A variation of b above that avoids dead ends: At each step you choose twice. First, randomly chose an item. Second, randomly choose where to place it. At the Kth step there are k optional places to put the item (the new item can be injected between two existing items). Naturally, you only choose from allowed places.
Money!
arrange your lists into a list of lists
save each item in the list as a tuple with the list index in the list of lists
loop n*m times
on even turns - flatten into one list and just rand pop - yield the item and the item group
on odd turns - temporarily remove the last item group and pop as before - in the end add the removed group back
important - how to avoid deadlocks?
a deadlock can occur if all the remaining items are from one group only.
to avoid that, check in each iteration the lengths of all the lists
and check if the longest list is longer than the sum of all the others.
if true - pull for that list
that way you are never left with only one list full
here's a gist with an attempt to solve this in python
https://gist.github.com/YontiLevin/bd32815a0ec62b920bed214921a96c9d
A very quick and simple method i am trying is:
random shuffle
loop over the pairs in the list:
if pair is bad:
loop over the pairs in the list:
if both elements of the new pair are different than the bad pair:
swap the second elements
break
will this always find a solution? will the solutions have the same distribution as naive shuffling until finding a legit solution?
Imagine we have a sorted list with size P. How can we choose N indices for which the values reflect the range of the list more smoothly. For example if our list is:
List=[0,0,0,0,0,0,0,0,0,0.1,0.1,0.9,0.91,0.91,0.92,0.99,0.99,0.99]
Then how we choose let's say 5 indices that somehow shows the full range of the list?
In this example it would be something like :
indices=[0,9,11,14,15]
The final indices list doesn't have to be exactly like the one I wrote here though
This will give you a starting point:
[List.index(x) for x in set(List)]
Now this may have too many elements but "somehow" is totally subjective and not a clear enough definition for what you need to do. As a default you can keep the first and last element, then randomly pick as many as you require from the "middle".
When I enumerate through a list, is there an intended, pythonic way of obtaining the last index value provided?
Something that would get the equivalent of this:
highest = None
for index, value in enumerate(long_list):
# do stuff with index and value
highest = index
return highest
This approach I don't like. It has hundreds of unnecessary variable assignments. Also, it's ugly.
Background: I have an ordered list build with a RDBS and SQLAlchemy, using numbers as indexes in the relation table. Also I store the highest used index number in the list table, for easy appending of new entries (without extra max lookup on relation table). For when things get messed up, for whatever reason, I included a reorg function, that rebuilds indexes starting from 0 (to remove any gaps). I to that by for-enumerate-iterating over the association table. After that I need to count them or max the index, to get my new highest index value for the list table. That kinda bugs me.
Suggestions? Preferably something that works in 2.7.
To get the last index of a list
len(mylist)-1
To get the last element of a list you can simply use a negative index.
mylist[-1]
I am currently trying write a function to use the position of a min value on one list to reference a string on another list.
I have two list, one with states names and another with floats. I am using the min method to get the minimum value of the float list. The problem is, how I use an index to mark the position of that value then use it to return the state that holds the same position on the other list?
This is the code I am currently using, but it does not go all the way through the list before it returns a value, which is way too soon in the list.
def stateheart_min():
for item in heartdis_flt:
heartcount=0
heartcount+=1
min_index=0
if item == min(heartdis_flt):
min_index=heartcount
return states_fin[min_index:min_index+1]
This is a bit terse to read, but here is an alternative way to do it. You can use min to find the minimum value in values. Then you can use index to find the index at which the minimum occurs in the list. You can then use that returned index to index the correct element from states.
states = ['NY', 'PA', 'CA', 'MI']
values = [15.0, 17.5, 3.5, 25.4]
>>> states[values.index(min(values))]
'CA'
Try this:
index = min(zip(values, range(len(values))))[1]
This first builds a list of pairs, each having a value as first item and its index as second item. So when you find the minimum, the first item still has the main impact (the index will only be taken into account if the values are equal). Taking the index is then done using [1] in the end.
Not entirely sure what you are asking, but a dictionary might be a better choice. Also setting heartcount=0 inside the loop resets the variable back to 0 each iteration. Check your variables inside the loop.