Print both the duplicate values name from the nested list - python

students=[['Ash',85.25],['Kai',85.25],['Ray',75],['Jay',55.5]]
output:Ash
Kai
I'm trying to solve a task and i'm new in python.I am not getting what i want can anyone explain me how one can do it

One option would be to group the values into a defaultdict(list):
>>> from collections import defaultdict
>>>
>>> students = [['Ash',85.25],['Kai',85.25],['Ray',75],['Jay',55.5]]
>>> d = defaultdict(list)
>>> for value, key in students:
... d[key].append(value)
...
>>> for value in d.itervalues():
... if len(value) > 1:
... print(value)
...
['Ash', 'Kai']

I would do it like that:
students = [['Ash', 85.25], ['Kai', 85.25], ['Ray', 75], ['Jay', 55.5]]
common_names = []
for i, i_x in enumerate(students):
for i_y in students[:i] + students[i + 1:]:
if i_x[1] == i_y[1]:
common_names.append(i_x[0])
print(common_names)
#['Ash', 'Kai']
# or if you want it to print every entry in a single line:
print('\n'.join(x for x in common_names))
#Ash
#kai
Explain:
I grab an object from the original list students. Object is i_x and its ['Ash', 85.25] on the first iteration for example.
Then i slice the list students[:i] + students[i + 1:] to create another one in memory that contains all the elements of the original one apart from i_x
I check to see if there is any item in the newly created list that has the same [1] index value as that of i_x. If yes, i append the i_x[0] value to a third list that holds the results.
I do this for as many elements as there are originally in the students list.
Can anybody provide a list comprehension for the above?

Related

How to get dictionary keys using a tuple, where dictionary keys are stored in list and values in tuple

dictionary = {}
my_list = ['a','b','c','d']
for i in range(len(my_list)-1):
dictionary[my_list[i]] = (my_list[i],)
for i in sorted (dictionary.keys()):
k = dictionary[i]
"""code here"""
For the above code I need to get the output as :
a
b
c
I know if we put print(i), we will get the desired output, but the answer expected is in terms of K.
Actual answer is: print(k[0]),which I am unable to understand.
Thanks
Since you define values of dictionary equal to a tuple here:
dictionary[my_list[i]] = (my_list[i],)
k is a tuple which means for it to print the actual value you need to get the first item in k by using the following:
dictionary = {}
my_list = ['a','b','c','d']
for i in range(len(my_list)-1):
dictionary[my_list[i]] = (my_list[i],)
for i in sorted (dictionary.keys()):
k = dictionary[i]
print(k[0])
Output:
a
b
c
k[0] just gets the first item in the tuple ('a',). This makes it print a instead of ('a',).

Add the key of a duplicated value to a list python

I have a dictionary of students like dic={1:[1,2],2:[1],3:[1,4]}. I need to sort it, and see if the students have the same values. If that happens, the student that comes up first has priority and the other student has 2 options. For example, in the example above, nothing happens to student 1, student 2 should be added to a separate list since the value 1 has already been used, and student 3 since it has a value that hasn't appeared before, nothing happens to it too. So basicly the output I would need for that example would be [2].
I managed to sort the dictionary by doing sorted(dic.items(), key=lambda t: t[0]) but I don't know how to compare them, the only thing I know is that after the comparison I would have to do something like
list=[]
list.append(number)
You should use a set to cumulatively keep the previous values, and iterate your dictionary.
Code could be:
prev = set() # no values initialy seen
new_list = [] # no student intialy in the new liest
for st, vals in dic.items(): # iterate on dic
if set(vals).issubset(prev): # is there no new value?
new_list.append(st) # add the student to new_list
prev = prev.union(set(vals)) # and add its values to the seen set
With your example, we get as expected [2] for new_list.
For each element you can check whether it is a subset of any previous values with O(n2) complexity
dic={1:[1,2],2:[1],3:[1,4]}
st_values = list(dic.values())
keys = list(dic.keys())
output = []
for i,v in enumerate(st_values):
for j in range(0, i):
if(set(v).issubset(st_values[j])):
output.append(keys[i])
print(output)
[2]
You can use sets. Since the sorted() function you used returns a list of tuples:
dic = sorted(dic.items(), key=lambda t: t[0])
appeared=set()
t=[]
for item in dic:
if not set(item[1]).issubset(appeared):
appeared.update(item[1])
else:
t.append(item[0])
print(f'Result: {t}')
Output:
Result: [2]

Check most common occurrence of a value of one list in a separate list

I have a list of numbers.
somelist = [5.000007,5.00099,5.0000075,5.0000075,5.0000075,5.0000099,5.00099,5.0000080,5.0000081,5.00099,5.0000080,5.0000096,5.0000087,5.008,5.00099,5.00000009]
I’m using the following to produce a unique list of the 3 lowest values:
def lowest_three(somelist):
lowest_unique = set(somelist)
return nsmallest(3, lowest_unique)
It produces the output:
[5.00000009, 5.000007, 5.0000075]
Now I want a separate function to tell me which of the three lowest values is the most commonly occuring in the original list.
So I want it to tell me that 5.0000075 is the most common number from the lowest_three list in the original list (somelist).
I’ve tried the following but it’s not working (it’s currently producing an output of 5.00099 which isn’t even in the lowest_three list).
def most_common_lowest(somelist):
for x in lowest_three(somelist):
return max(set(somelist), key=somelist.count)
How can achieve this?
Now I want a separate function to tell me which of the three lowest values is the most commonly occuring in the original list.
def most_common_lowest(somelist):
for x in lowest_three(somelist):
return max(set(somelist), key=somelist.count)
That code doesn't make sense. Should be:
def most_common_lowest(somelist):
return max(lowest_three(somelist), key=somelist.count)
You could possibly collect the counts with collections.Counter(), with only values from somelist that exist in top_three, then take the most_common of this:
from heapq import nsmallest
from collections import Counter
somelist = [5.000007,5.00099,5.0000075,5.0000075,5.0000075,5.0000099,5.00099,5.0000080,5.0000081,5.00099,5.0000080,5.0000096,5.0000087,5.008,5.00099,5.00000009]
def lowest_three(somelist):
lowest_unique = set(somelist)
return nsmallest(3, lowest_unique)
top_three = lowest_three(somelist)
# [5.00000009, 5.000007, 5.0000075]
freqs = Counter(x for x in somelist if x in top_three)
# Counter({5.0000075: 3, 5.000007: 1, 5.00000009: 1})
print(freqs.most_common(1)[0][0])
# 5.0000075
O you could group them in a collections.defaultdict, and take the max manually:
from collections import defaultdict
from operator import itemgetter
filtered_values = [x for x in somelist if x in top_three]
# [5.000007, 5.0000075, 5.0000075, 5.0000075, 5.00000009]
freqs = defaultdict(int)
for val in filtered_values:
freqs[val] += 1
# defaultdict(<class 'int'>, {5.000007: 1, 5.0000075: 3, 5.00000009: 1})
print(max(freqs.items(), key = itemgetter(1))[0]) # or key = lambda x: x[1]
# 5.0000075
Given the returned list from lowest_three, you can use list.count:
somelist = [5.000007,5.00099,5.0000075,5.0000075,5.0000075,5.0000099,5.00099,5.0000080,5.0000081,5.00099,5.0000080,5.0000096,5.0000087,5.008,5.00099,5.00000009]
new_list = lowest_three(somelist)
final_data = sorted(new_list, key=lambda x:somelist.count(x))[-1]
Output:
5.0000075
One option is to use collections.Counter.
from collections import Counter
counts = Counter(somelist)
lowest = lowest_three(somelist)
for num in lowest:
print counts[num]
// i think you better write an algorithm for this operation your self (for the practice)
a simple algorithm :
create a map contining only those 3 elements ,(witch you already found), as keys, and 0 as value.
run over the array and for each element in the array chack if the map contains him, if it does inc the value by 1 (map[key] = map[key]+1) .
iterate over your map and find the key with the highest value.
(it's like a counters array but with map data structure)
Use Counter from collections module and use sorted function, twice once for getting the 3 minimum elements and and second time for getting maximum occurring element
from collections import Counter
somelist = [5.000007,5.00099,5.0000075,5.0000075,5.0000075,5.0000099,5.00099,5.0000080,5.0000081,5.00099,5.0000080,5.0000096,5.0000087,5.008,5.00099,5.00000009]
lowest_three=sorted(Counter(somelist).items(), key=lambda i: i[0])[:3]
print(sorted(lowest_three,key=lambda i :-i[1])[0])
OUTPUT
(5.0000075, 3)
You can use the function min. It might solve your problem out.
#!/usr/bin/python
var list = [5.00000009, 5.000007, 5.0000075]
print "min value element : ", min(list)
https://www.tutorialspoint.com/python/list_min.htm
Everyone suggesting you collection module , You can do without collection and in few lines , Here you go:
somelist = [5.000007,5.00099,5.0000075,5.0000075,5.0000075,5.0000099,5.00099,5.0000080,5.0000081,5.00099,5.0000080,5.0000096,5.0000087,5.008,5.00099,5.00000009]
values=[5.00000009, 5.000007, 5.0000075]
track={}
for j,i in enumerate(somelist):
if i in values:
if i not in track:
track[i]=1
else:
track[i]+=1
print(max(list(map(lambda x:(track[x],x),track))))
output:
(3, 5.0000075)

Fastest way to get the index of the first sublist that contains value

I have a list of lists in python of the form
A=[[1,2,3,4],
[5,6,7,8],
[9,10,11,12]]
I need to get a fast way to get the row index of an element in that structure.
method(2) = 0
method(8) = 1
method(12) = 2
and so on. As always, the fastest the method the better, as my actual list of lists is quite large.
In this state, the data structure (list of lists) is not quite convenient and efficient for the queries you want to make on it. Restructure it to have it in a form:
item -> list of sublist indexes # assuming items can be present in multiple sublists
This way the lookups would be instant, by key - O(1). Let's use defaultdict(list):
>>> from collections import defaultdict
>>>
>>> d = defaultdict(list)
>>> for index, sublist in enumerate(A):
... for item in sublist:
... d[item].append(index)
...
>>> d[2]
[0]
>>> d[8]
[1]
>>> d[12]
[2]
It is very simple using next() with a generator expression:
def method(lists, value):
return next(i for i, v in enumerate(lists) if value in v)
The problem with that is that it will have an error if value does not occur. With a slightly longer function call, you can make a default of -1:
def method(lists, value):
return next((i for i,v in enumerate(lists) if value in v), -1)
Here is another way using numpy
import numpy
A = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
my_array = numpy.array(A)
numpy.where(my_array==2) ## will return both the list and the index within the list
numpy.where(my_array==12)
## As a follow up if we want only the index we can always do :
numpy.where(my_array==12)[0][0] # will return 2 , index of list
numpy.where(my_array==12)[1][0] # will return 3 , index within list
find operation in list is linear. Following is simple code in python to find an element in list of lists.
A=[[1,2,3,4],
[5,6,7,8],
[9,10,11,12]]
def method(value):
for idx, list in enumerate(A):
if value in list:
return idx
return -1
print (method(12))

Trying to add to dictionary values by counting occurrences in a list of lists (Python)

I'm trying to get a count of items in a list of lists and add those counts to a dictionary in Python. I have successfully made the list (it's a list of all possible combos of occurrences for individual ad viewing records) and a dictionary with keys equal to all the values that could possibly appear, and now I need to count how many times each occur and change the values in the dictionary to the count of their corresponding keys in the list of lists. Here's what I have:
import itertools
stuff=(1,2,3,4)
n=1
combs=list()
while n<=len(stuff):
combs.append(list(itertools.combinations(stuff,n)))
n = n+1
viewers=((1,3,4),(1,2,4),(1,4),(1,2),(1,4))
recs=list()
h=1
while h<=len(viewers):
j=1
while j<=len(viewers[h-1]):
recs.append(list(itertools.combinations(viewers[h-1],j)))
j=j+1
h=h+1
showcount={}
for list in combs:
for item in list:
showcount[item]=0
for k, v in showcount:
for item in recs:
for item in item:
if item == k:
v = v+1
I've tried a bunch of different ways to do this, and I usually either get 'too many values to unpack' errors or it simply doesn't populate. There are several similar questions posted but I'm pretty new to Python and none of them really addressed what I needed close enough for me to figure it out. Many thanks.
Use a Counter instead of an ordinary dict to count things:
from collections import Counter
showcount = Counter()
for item in recs:
showcount.update(item)
or even:
from collections import Counter
from itertools import chain
showcount = Counter(chain.from_iterable(recs))
As you can see that makes your code vastly simpler.
If all you want to do is flatten your list of lists you can use itertools.chain()
>>> import itertools
>>> listOfLists = ((1,3,4),(1,2,4),(1,4),(1,2),(1,4))
>>> flatList = itertools.chain.from_iterable(listOfLists)
The Counter object from the collections module will probably do the rest of what you want.
>>> from collections import Counter
>>> Counter(flatList)
Counter({1: 5, 4: 4, 2: 2, 3: 1})
I have some old code that resembles the issue, it might prove useful to people facing a similar problem.
import sys
file = open(sys.argv[-1], "r").read()
wordictionary={}
for word in file.split():
if word not in wordictionary:
wordictionary[word] = 1
else:
wordictionary[word] += 1
sortable = [(wordictionary[key], key) for key in wordictionary]
sortable.sort()
sortable.reverse()
for member in sortable: print (member)
First, 'flatten' the list using a generator expression: (item for sublist in combs for item in sublist).
Then, iterate over the flattened list. For each item, you either add an entry to the dict (if it doesn't already exist), or add one to the value.
d = {}
for key in (item for sublist in combs for item in sublist):
try:
d[key] += 1
except KeyError: # I'm not certain that KeyError is the right one, you might get TypeError. You should check this
d[key] = 1
This technique assumes all the elements of the sublists are hashable and can be used as keys.

Categories

Resources