Sorting repeated elements - python

What I try to do is to write a function sort_repeated(L) which returns a sorted list of the repeated elements in the list L.
For example,
>>sort_repeated([1,2,3,2,1])
[1,2]
However, my code does not work properly. What did I do wrong in my code?
def f5(nums):
count = dict()
if not nums:
for num in nums:
if count[num]:
count[num] += 1
else:
count[num] = 1
return sorted([num for num in count if count[num]>1])
return []

if count[num]: will fail if the dictionary doesn't have the key already. Take a look at the various counter recipes on this site and use one instead.
Also, not nums is true if nums is an empty sequence, which means that the loop body will never be executed. Invert the condition.

Use a counter and check for values greater than 1
from collections import Counter
def sort_repeated(_list):
cntr = Counter(_list)
print sorted([x for x in cntr.keys() if cntr[x] > 1])
sort_repeated([7, 7, 1, 2, 3, 2, 1, 4, 3, 4, 6, 5])
>> [1, 2, 3, 4, 7]

Related

Why is my code not following the command?

def pairs(x):
for num in x:
if num == num :
return x
y = [2, 2, 2, 2, 2, 4, 3, 3]
pairs (y)
print (y)
this is returning [2, 2, 2, 2, 2, 4, 3, 3]
but I want to return [2,2,3]
I've tried 3 codes already other than this one
help me
Your code seems to be intended to find all the numbers that exist in pairs in the list. The best way would be (for a sorted list) to just cycle through the list and check successive elements.
Your code just matches if the current number is the same as the current numbers always returns true and returns all elements. A correct Code might be:
y = [2, 2, 2, 2, 2, 4, 3, 3]
y=sorted(y) # Sorts the given list
def pairs(arr):
i = 0 # Counter variable
res = [] #result list
while i < len(arr)-1:
if arr[i] == arr[i+1]:
res.append(arr[i]) # If the successive elements are the same, add
# it to the result array and since we have already
# checked the next element, increment the counter by
# two
i+=2
else:
i+=1 # If the elements are different we need to check the
# next element as well so increment by 1
return res
print(pairs(y))
You are comparing the element with itself which is always true. Here is the correct logic
y = [2, 2, 2, 2, 2, 4, 3, 3]
filt = []
i=0
while (i< (len(y)-1)):
if y[i] == y[i+1]:
filt.append(y[i])
i+=1
i+=1
print(filt)

Find count of number of pairs in the list

I have list of numbers:
[5, 4, 3, 4, 2, 1, 3, 5, 3, 5, 3, 5,]
A pair of numbers is the same 2 numbers. For example, 5 occurs 4 times, so we have 2 pairs of 5s. In the list above I can say I have 5 pairs. I want the output to count how many pairs of numbers are in the list.
I tried this, but got stuck.
list = [5,4,3,4,2,1,3,5]
print(list)
temp = 0
new_list = []
for index,x in enumerate(list):
elm_count = list.count(list[index])
if new_list:
for ind, y in enumerate(new_list):
if list[index] == new_list[ind]:
continue
if not elm_count % 2:
occ_count = elm_count/2
temp += occ_count
new_list.append(list[index])
continue
Simpler way to achieve this is using collections.Counter() with sum() as:
>>> my_list = [5, 4, 3, 4, 2, 1, 3, 5,3, 5, 3, 5,]
>>> sum(num//2 for num in Counter(my_list).values())
5
Here Counter() will generate a dict with number as key and count of occurrence of number in list as its value. Then I am iterating over its values and calculating the count of pairs for each number using generator expression, and doing summation on the count of all the pairs using sum().
You can refer below documents for more details:
collections.Counter() document
sum() document
To add, a solution without importing a package:
# Accepts a list of numbers as argument
def get_pairs(l):
already_counted = []
list_of_pairs = []
for i in l:
if not i in already_counted:
already_counted.append(i)
list_of_pairs.append(ar.count(i)//2)
return sum(list_of_pairs)
get_pairs([4,3,3,4,2,3,2,1,5]) # Run

Count elements in a list without using Counter

Should be returning a dictionary in the following format:
key_count([1, 3, 2, 1, 5, 3, 5, 1, 4]) ⇒ {
1: 3,
2: 1,
3: 2,
4: 1,
5: 2,
}
I know the fastest way to do it is the following:
import collections
def key_count(l):
return collections.Counter(l)
However, I would like to do it without importing collections.Counter.
So far I have:
x = []
def key_count(l):
for i in l:
if i not in x:
x.append(i)
count = []
for i in l:
if i == i:
I approached the problem by trying to extract the two sides (keys and values) of the dictionary into separate lists and then use zip to create the dictionary. As you can see, I was able to extract the keys of the eventual dictionary but I cannot figure out how to add the number of occurrences for each number from the original list in a new list. I wanted to create an empty list count that will eventually be a list of numbers that denote how many times each number in the original list appeared. Any tips? Would appreciate not giving away the full answer as I am trying to solve this! Thanks in advance
Separating the keys and values is a lot of effort when you could just build the dict directly. Here's the algorithm. I'll leave the implementation up to you, though it sort of implements itself.
Make an empty dict
Iterate through the list
If the element is not in the dict, set the value to 1. Otherwise, add to the existing value.
See the implementation here:
https://stackoverflow.com/a/8041395/4518341
Classic reduce problem. Using a loop:
a = [1, 3, 2, 1, 5, 3, 5, 1, 4]
m = {}
for n in a:
if n in m: m[n] += 1
else: m[n] = 1
print(m)
Or explicit reduce:
from functools import reduce
a = [1, 3, 2, 1, 5, 3, 5, 1, 4]
def f(m, n):
if n in m: m[n] += 1
else: m[n] = 1
return m
m2 = reduce(f, a, {})
print(m2)
use a dictionary to pair keys and values and use your x[] to track the diferrent items founded.
import collections
def keycount(l):
return collections.Counter(l)
key_count=[1, 3, 2, 1, 5, 3, 5, 1, 4]
x = []
dictionary ={}
def Collection_count(l):
for i in l:
if i not in x:
x.append(i)
dictionary[i]=1
else:
dictionary[i]=dictionary[i]+1
Collection_count(key_count)
[print(key, value) for (key, value) in sorted(dictionary.items())]

How to reverse list without in-built function [duplicate]

This question already has answers here:
How can I reverse a section of a list using a loop in Python?
(5 answers)
Closed 3 years ago.
I have this problem for homework and I have almost gotten it but not quite. I have to develop some code that takes a list and a number as parameters. The function returns a copy of the list with the first number of items reversed. I can not use in-built functions, slicing or reverse, I can only use append.() and range(). Would really appreciate someone's help with fixing my current code and maybe explaining how you fixed it? Thankyou!!!
str_list6 = ['e', 'd', 'u', 'd']
def length(my_list):
total = 0
for c in my_list:
total += 1
return total
def remove_value(my_list):
res = []
for i in range(length(my_list) -1, -1, -1):
res.append((my_list)[i])
return res
the example given:
numList = [1, 2, 3, 4, 5, 6, 7]
number = 4
The call to reverse(numList, number) should
return the new list
[4, 3, 2, 1, 5, 6, 7].
So my code currently simply reverses the list however (its hard to explain), it needs to reverse with the shift of the 'number'. Hopefully this make sense!
The problem here is that you are not taking into account the number to shift. In your example you are given two variables, the list and the number to shift (is this the position or the actual number you are looking for? - assuming position), yet your code only takes the list.
def remove_value(my_list, pos_to_reverse):
res = []
for i in range(pos_to_reverse-1, -1):
res.append(my_list[i])
for i in range(pos_to_reverse, length(my_list)-1):
res.append(my_list[i])
return res
You were getting close! I think the function below does what you want.
def reverse(numList,number):
# Make an empty list
reversedlist=[]
for i in range(number):
# i goes from 0 to number-1
reversedlist.append(numList[number-i-1])
# build a reversed list by adding each element
# of numList going in reverse order.
for i in range(number):
# i goes from 0 to number-1
numList[i]=reversedlist[i]
# change the first 'number' elements of the
# original list with the reversed list.
return numList
numList = [1, 2, 3, 4, 5, 6, 7]
number = 4
print(reverse(numList,number))
# prints: [4, 3, 2, 1, 5, 6, 7]
You can probably do like this.
l = [1, 2, 3, 4, 5, 6, 7]
n = 4
def solution(lst,n):
size = n
hiindex = size - 1
its = size//2
for i in range(0, its):
temp = lst[hiindex]
lst[hiindex] = lst[i]
lst[i] = temp
hiindex -= 1
return lst
print(solution(l,n))
You can use this tiny loop:
numList = [1, 2, 3, 4, 5, 6, 7]
number = 4
def reverse(l, n):
for i in range((n + 1) // 2):
l[i], l[n - i - 1] = l[n - i - 1], l[i]
return l
print(reverse(numList, number))
Output:
[4, 3, 2, 1, 5, 6, 7]

Code to Find Unique Number Slow and Inefficient?

I recently was working on a code problem on codewars to find a unique number in a list. My code works, however it is incredibly inefficient. I am not sure why this is the case. Below is my code posted:
I think the problem might be with the fact that I am copying the list every single time I iterate (maybe).
def find_uniq(arr):
equal_check = 0
for i in arr:
arr_new = arr.copy()
arr_new.remove(i)
if i not in arr_new:
equal_check = i
return equal_check
Use collections.Counter, get the ones with count of 1:
from collections import Counter
def find_uniq(arr):
c = Counter(arr)
return [number for number,count in c.most_common() if count == 1]
print(find_uniq( [1,2,3,4,2,3,4,5,6,4,5,6,7,8,9])) # [1, 7, 8, 9]
This takes about O(2*n) so O(n) as 2 is constant.
collection.defaultdict with int, get the ones with count of 1:
# defaultdict
from collections import Counter , defaultdict
def find_uniq(arr):
c = defaultdict(int)
for a in arr:
c[a] += 1
return [number for number,count in c.items() if count == 1]
print(find_uniq( [1,2,3,4,2,3,4,5,6,4,5,6,7,8,9])) # [1, 7, 8, 9]
This takes about O(2*n) so O(n) as 2 is constant - it is slighty faster then Counter because of C-optimizations inside the implementation (see f.e. Surprising results with Python timeit: Counter() vs defaultdict() vs dict()).
normal dicts and setdefault or test/add, get the ones with count of 1:
# normal dict - setdefault
def find_uniq(arr):
c = dict()
for a in arr:
c.setdefault(a,0)
c[a] += 1
return [number for number,count in c.items() if count == 1]
print(find_uniq( [1,2,3,4,2,3,4,5,6,4,5,6,7,8,9])) # [1, 7, 8, 9]
# normal dict - test and add
def find_uniq(arr):
c = dict()
for a in arr:
if a in c:
c[a] += 1
else:
c[a] = 1
return [number for number,count in c.items() if count == 1]
print(find_uniq( [1,2,3,4,2,3,4,5,6,4,5,6,7,8,9])) # [1, 7, 8, 9]
Setdefault creates the defaultvalue every time - it is slower then Counter or defaultdict and faster then using test/add.
itertools.groupby (needs sorted list!), get the ones with count of 1:
from itertools import groupby
def find_uniq(arr):
return [k for (k,p) in groupby(sorted(arr)) if len(list(p)) == 1]
print(find_uniq( [1,2,3,4,2,3,4,5,6,4,5,6,7,8,9])) # [1, 7, 8, 9]
groupby needs a sorted list, list sort alone is O(n * log n) and in combination this is slower then the other approaches.
One approach is to use two sets, one to stored those values that are seen once, and those that are more that once, then just find the difference:
data = [1, 2, 3, 4, 2, 3, 4, 5, 6, 4, 5, 6, 7, 8, 9]
first, second = set(), set()
for e in data:
if e not in first:
first.add(e)
else:
second.add(e)
res = first - second
print(res)
Output
{8, 1, 9, 7}

Categories

Resources