I have 2 lists..
list_a = ['Grapes/testfile.csv','Apples/testfile.csv','Pears/testfile.csv','Pears/testfile2.csv']
ref_list = ['Pears','Grapes','Apples']
I need to use ref_list list to order list_a.
More context, list_a will always have the string from ref_list before the / but the length of ref_list will never match that of list_a.. Also I dont want to order reverse alphabetically.
Expected Output:
ordered_list = ['Pears/testfile.csv','Pears/testfile2.csv','Grapes/testfile.csv','Apples/testfile.csv']
I've tried many variations, referencing SO but I cant get this to work.. I just cant work out a way to reference the first list here is my attempt which obviously doesn't work as its not referencing ref_list but my logic is to use string method startswith()
Something like:?
ordered_list = sorted(list_a, key = lambda x: x.startswith())
Use split() to extract the word before /.
Then use index() to get the position of the starting word in ref_list, and use that for the sorting key.
ordered_list = sorted(list_a, key = lambda x: ref_list.index(x.split('/')[0]))
This answer may not be the most elegant, but it works:
sorted_list = list()
for key in ref_list:
sorted_list += [sorted_value for sorted_value in list_a if \
sorted_value.startswith(key)]
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]
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)
I have a list of filenames. I need to group them based on the ending names after underscore ( _ ). My list looks something like this:
[
'1_result1.txt',
'2_result2.txt',
'3_result2.txt',
'4_result3.txt',
'5_result4.txt',
'6_result1.txt',
'7_result2.txt',
'8_result3.txt',
]
My end result should be:
List1 = ['1_result1.txt', '6_result1.txt']
List2 = ['2_result2.txt', '3_result2.txt', '7_result2.txt']
List3 = ['4_result3.txt', '8_result3.txt']
List4 = ['5_result4.txt']
This will come down to making a dictionary of lists, then iterating the input and adding each item to its proper list:
output = {}
for item in inlist:
output.setdefault(item.split("_")[1], []).append(item)
print output.values()
We use setdefault to make sure there's a list for the entry, then add our current filename to the list. output.values() will return just the lists, not the entire dictionary, which appears to be what you want.
using defaultdict from collections module:
from collections import defaultdict
output = defaultdict(list)
for file in data:
output[item.split("_")[1]].append(file)
print output.values()
using groupby from itertools module:
data.sort(key=lambda x: x.split('_')[1])
for key, group in groupby(data, lambda x: x.split('_')[1]):
print list(group)
Starting with Python 2.4, both list.sort() and sorted() added a key parameter to specify a function to be called on each list element prior to making comparisons.
The value of the key parameter should be a function that takes a single argument and returns a key to use for sorting purposes. This technique is fast because the key function is called exactly once for each input record.
So if l is the name of your list then you could use something like :
l.sort(key=lambda s: s.split('_')[1])
More information about key functions at here
Currently, I have a list of lists called result which will contain values like this, for example:
result[1] = [John, 0.32]
result[2] = [Mikey, 1.90]
result[3] = [Sarah, 1.31]
result[4] = [Nancy, 0.49]
result[5] = [Billy, 0.13]
I want to however, sort this in descending order by the number which is held in the index space [1]. So the system will return the values in that order. Would I just have to use the sorted() function and call up the index where the value is held? I do not need to resort the list is it is necessary, i will just need to output the values in descending order.
How would I go about doing this exactly?
Use the key parameter in the sorted function.
sorted(result, key = lambda x:x[1], reverse = True)
The reverse = True makes sure that the items are sorted in the descending order. The important thing to be noted here is the key parameter.
key = lambda x:x[1]
We pass a lambda function to the key parameter, which accepts one parameter. sorted picks each element from result and pass that to the key function. In our case it is the tuples. The key function returns the second item in the tuples. So, the second item in the tuple will be used as the value of the tuple itself, while sorting. It means that when we comapre [John, 0.32] and [Mikey, 1.90], we will be actually comparing 0.32 and 1.90 only.
sorted doesn't change the actual list, but creates a new sorted list. But, if you want to sort the list itself, then you can use list.sort method, like this
result.sort(key = lambda x:x[1], reverse = True)
You can do that using sorted:
new_list = sorted(old_list, key=lambda x: x[1], reverse=True)
or using sort:
old_list.sort(key=lambda x: x[1], reverse=True)