Find and remove least common element in array (Python) - python

I am trying to find the least common element in an array of integers and remove it, and return the list in the same order.
This is what I have done, but when the list is [1, 2, 3, 4, 5], my function should return [], but returns [2, 4] instead.
def check(data):
for i in data:
if data.count(i) <= 1:
data.remove(i)
return data
data = [1, 2, 3, 4, 5]
print check(data)

Deleting items from a list you are iterating over causes you to skip items (ie the next item following each one you delete).
Instead, make a new list containing only the values you want to keep.
from collections import Counter
def check(data):
ctr = Counter(data)
least = min(ctr.values())
return [d for d in data if ctr[d] > least]

You shouldn't modify (especially delete) elements from a list while you are iterating over it.
What happened is:
Initially the iterator is at the 1st element, i.e. i = 1
Since d.count(1) is 1, so you delete 1 from the list.
The list is now [2,3,4,5], but the iterator advances to the 2nd element which is now the 3.
Since d.count(3) is 1 you delete it making the list [2,4,5]
The iterator advances to the 3rd element which is now 5.
Again you delete the 5 making the list [2,4].
Your algorithm should:
Get a count of all elements
Find the smallest count.
Find the elements with the smallest count.
Remove the elements found in step 3 from the list.

You shouldn't check data.count(i) <= 1. What happens in this case: [1, 1, 2, 2, 3, 3, 3]? 1 and 2 are the least common elements but you will never delete them. Likewise it is a bad idea to mutate a list in a for loop.
One thing you can do is use the Counter class.
Take an appropriate slice of the tail of the most_common() method (they entries get less frequent as you go down the list, so this is why you take the tail as opposed to the head).
Then you can repeatedly search the list for these occurrences and remove them until their are no occurrences left.

one another try:
def check(data):
ctr = Counter(data)
keys = ctr.keys()
vals = ctr.values()
least = []
m = min(vals)
for i in range(0,len(vals)):
if vals[i] == m:
least.append(keys[i])
print least
data = [1, 2, 3, 4, 5,1]
result = check(data)

Related

How remove() function was executed in python?

Actually I was working with this code:
m=[0,1,2,3,4,5,6,7]
for i in m:
m.remove(i)
print(m)
This looks pretty simple.
for i in m:
print(i)
will print every elements in the list m. So the for part in our code will extract every elements of the list and remove it one by one. So the output that I except is [].
But I got [1,3,5,7].
How it can be the output and where I was wrong?
when you use (for i in m), i starts from index zero so i is the element of index 0 which its value is 0 then in for loop you'll delete zero value.
now your list is [1,2,3,4,5,6,7] and i is the element of index 1 which its value is 2.
after deleting 2 your list would be like [2,3,4,5,6,7], now i is the element of index 2 which its value is 4 and ....
here is how this for loop works and why the output is like that.
to remove all element in a list you can use:
for i in range(len(m)):
m.remove(m[0])
or
m.clear()
If you know how to use a debugger, that would be the ideal way to diagnose this, otherwise, try running this code to see what's going on:
x = [0, 1, 2, 3, 4, 5, 6, 7]
for i in x.copy():
x.remove(i)
print(x)
print(x)
m = [0, 1, 2, 3, 4, 5, 6, 7]
for i in m:
m.remove(i)
print(m)
print(m)
During a given execution, the for loop accesses an element and then deletes it. For example, it first deletes the element at index 0, with value 0, leaving you with [1, 2, 3, 4, 5, 6, 7]. Then it moves on to the element at index 1, value 2, and deletes that, leaving you with [1, 3, 4, 5, 6, 7].
In general, avoid messing around with a list in Python. If you have to delete all elements, use m.clear(). If you have to delete some elements or do some other stuff, prefer to use list comprehension to create a new object.
What happens here is, you're removing items in the list on the go.
Eg,
On the first remove() call, it removes 0 from the list (current
index is 0).
On the second remove() call, the current index is 1,
but the list contains [1,2,3,...]. Now the the index 1 contains "2"
instead of "1". Because 0 has been removed and the size of list is
just changed.
So to clear list in python, you can use,
m.clear()
i don`t know why it is not remove each item, but i worked on it and it works like this:
m=[0,1,2,3,4,5,6,7]
while m != []:
[m.remove(i) for i in m]
print(m)

How to manipulate a list with recursive function?

I'm trying to manipulate a given list in an unusual way (at least for me).
Basically, I have the list a (also image 1), it has the first index as principal. Now, I want to iterate through the other indexes and if a certain value match with one of those in the first index, I want to insert the sublist of this index inside the first one.
I don't know if I was clear enough, but the goal should be the list b (also image 2). I think a recursive function should be used here, but I don't know how. Do you guys think it's possible?
Original list:
a = [[1,2,3],[2,5],[6,3],[10,5]]
Expected Output:
b = [[1,2,[2,5,[10,5]],3,[6,3]]]
You could use a dictionary to record where the first occurrence of each number is found, recording the list in which it was found, and at which index. If then a list is found that has a value that was already encountered, the recorded list can be mutated having the matching list inserted. If there was no match (which is the case for the very first list [1,2,3]), then this list is just appended to the result.
Because insertion into a list will impact other insertion points, I suggest to first collect the insertion actions, and then apply them in reversed order:
Here is the code for that:
def solve(a):
dct = {}
result = []
insertions = []
for lst in a:
found = None
for i, val in enumerate(lst):
if val in dct:
found = val
else:
dct[val] = [lst, i]
if found is None:
result.append(lst)
else:
insertions.append((*dct[found], lst))
for target, i, lst in reversed(insertions):
target.insert(i + 1, lst)
return result
# Example run:
a = [[1,2,3],[2,5],[6,3],[10,5]]
print(solve(a))
Output:
[[1, 2, [2, 5, [10, 5]], 3, [6, 3]]]

Python: 2 Index Location Brackets for a List

list1 = [1, 2, 3, 4]
element = list1[1:][1]
print(element)
Why does it print 3?
How is this evaluated? Does it first take the elements of list1 that are from index 1: then it takes the 1 index of that?
Python's grammar specifies how it is evaluated, since it constructs a syntax tree of your program.
Without going much into technical detail, such indexing is left recursive. This means that:
foo[bar][qux]
is short for:
(foo[bar])[qux]
so such indices are evaluated left-to-right.
It is evaluated like:
list1 = [1, 2, 3, 4]
temp = list1[1:] # create a sublist starting from the second item (index is 1)
element = temp[1] # obtain the second item of temp (index is 1)
(of course in reality, no temp variable is created, but the list itself is a real object stored in memory, and thus also might change state, etc.).
So first we slice starting from the second item, this results in a list [2, 3, 4], and then we obtain the second item of that list, so 3.

Check if all values of a list are less than a certain number, if not set it to that number

I have a list in python and I want to make sure that all values in the list are greater than some value. If not then I want to set it to that value.
eg: let us assume the list is
a = [1,2,3,4]
and the value to compare is 3. So I want the list to become
a = [3,3,3,4]
I can do this by iterating through all the elements in the list. Is there a better way to do that?
You can reconstruct the list with a simple conditional expression and list comprehension, like this
a = [1, 2, 3, 4]
print [item if item > 3 else 3 for item in a]
# [3, 3, 3, 4]
For every item in a, it checks if it is greater than 3, then use item as it is otherwise use 3.
This is similar but very efficient than the following,
result = []
for item in a:
if item > 3:
result.append(item)
else:
result.append(3)
But remember that list comprehension creates a new list. So, you have may have to do
a = [item if item > 3 else 3 for item in a]

How come my function is only looping through three elements within my list

I am trying to loop through all the elements (8 of them) in my list, but my function is only providing me with 4 of them. This is for an application I am making as a personal project.
import urllib
def get_followers():
count = 0
link = ['http://twitter.com/statuses/user_timeline.xml?screen_name=beratmahmuzlu', 'http://twitter.com/statuses/user_timeline.xml?screen_name=lidiazuin', 'http://twitter.com/statuses/user_timeline.xml?screen_name=kelewele_boham', 'http://twitter.com/statuses/user_timeline.xml?screen_name=AwangHafizam', 'http://twitter.com/statuses/user_timeline.xml?screen_name=BRAYANLVN', 'http://twitter.com/statuses/user_timeline.xml?screen_name=zezol_pl', 'http://twitter.com/statuses/user_timeline.xml?screen_name=brysonwong', 'http://twitter.com/statuses/user_timeline.xml?screen_name=racsozara']
while count < len(link):
print link[count]
link.pop()
count = count + 1
You are popping the list and basing your loop off of the count of the list.
try a for loop instead:
for lnk in link:
print lnk
link.pop() removes an element and len(link) gives you the new length of the list at each iteration, looping thus thru only the half of your list.
def get_followers():
count = 0
link = [0, 1, 2, 3, 4, 5, 6, 7, 8]
l = len(link)
while count < l:
print link.pop()
count = count + 1
This is the correct implementation, although there are many more cleaner way to iterate over a list in python, this is one of the simplest:
def get_followers():
link = [0, 1, 2, 3, 4, 5, 6, 7, 8]
for l in link:
print l
I am trying to loop through all the elements (8 of them) in my list
Then do that. Don't set up a counter variable, repeatedly use it to index into the list, remove elements from the list and increment the counter. Just loop through the elements.
If I asked you to crack a dozen eggs, you would not need to write numbers on them, or think about how many eggs you'd already cracked. You'd just do it.
So just do it.
for link in links:
print link

Categories

Resources