Related
If I want to combine lists inside list based on element value how can I achieve that?
suppose if list
lis = [['steve','reporter','12','34','22','98'],['megan','arch','44','98','32','22'],['jack','doctor','80','32','65','20'],['steve','dancer','66','31','54','12']]
here list containing 'steve' appears twice so I want to combine them as below
new_lis = [['steve','reporter','12','34','22','98','dancer','66','31','54','12'],['megan','arch','44','98','32','22'],['jack','doctor','80','32','65','20']]
I tried below code to achieve this
new_dic = {}
for i in range(len(lis)):
name = lis[i][0]
if name in new_dic:
new_dic[name].append([lis[i][1],lis[i][2],lis[i][3],lis[i][4],lis[i][5]])
else:
new_dic[name] = [lis[i][1],lis[i][2],lis[i][3],lis[i][4],lis[i][5]]
print(new_dic)
I ended up creating a dictionary with multiple values of lists as below
{'steve': ['reporter', '12', '34', '22', '98', ['dancer', '66', '31', '54', '12']], 'megan': ['arch', '44', '98', '32', '22'], 'jack': ['doctor', '80', '32', '65', '20']}
but I wanted it as single list so I can convert into below format
new_lis = [['steve','reporter','12','34','22','98','dancer','66','31','54','12'],['megan','arch','44','98','32','22'],['jack','doctor','80','32','65','20']]
is there a way to tackle this in different way?
There is a differnet way to do it using groupby function from itertools. Also there are ways to convert your dict to a list also. It totally depends on what you want.
from itertools import groupby
lis = [['steve','reporter','12','34','22','98'],['megan','arch','44','98','32','22'],['jack','doctor','80','32','65','20'],['steve','dancer','66','31','54','12']]
lis.sort(key = lambda x: x[0])
output = []
for name , groups in groupby(lis, key = lambda x: x[0]):
temp_list = [name]
for group in groups:
temp_list.extend(group[1:])
output.append(temp_list)
print(output)
OUTPUT
[['jack', 'doctor', '80', '32', '65', '20'], ['megan', 'arch', '44', '98', '32', '22'], ['steve', 'reporter', '12', '34', '22', '98', 'dancer', '66', '31', '54', '12']]
Not sure whether this snippet answers your question or not. This is not a fastest approach in terms to time complexity. I will update this answer if I can solve in a better way.
lis = [['steve','reporter','12','34','22','98'],['megan','arch','44','98','32','22'],['jack','doctor','80','32','65','20'],['steve','dancer','66','31','54','12']]
new_lis = []
element_value = 'steve'
for inner_lis in lis:
if element_value in inner_lis:
if not new_lis:
new_lis+=inner_lis
else:
inner_lis.remove(element_value)
new_lis+=inner_lis
lis.remove(inner_lis)
print([new_lis] + lis)
Output
[['steve', 'reporter', '12', '34', '22', '98', 'dancer', '66', '31', '54', '12'], ['megan', 'arch', '44', '98', '32', '22'], ['jack', 'doctor', '80', '32', '65', '20']]
Would anyone be able to give me a tip on how to split a nested dictionary into separate nested dictionaries based on a common key name called score and the value of score?
For example break up this nested dictionary nested_group_map_original :
nested_group_map_original = {
'group_l1n': {'score': 0.12949562072753906, 'VMA-1-1': '14', 'VMA-1-2': '13', 'VMA-1-3': '15', 'VMA-1-4': '11', 'VMA-1-5': '9', 'VMA-1-7': '7', 'VMA-1-10': '21', 'VMA-1-11': '16'},
'group_l1s': {'score': -0.40303707122802734, 'VMA-1-6': '8', 'VMA-1-8': '6', 'VMA-1-9': '10', 'VMA-1-12': '19', 'VMA-1-13': '20', 'VMA-1-14': '37', 'VMA-1-15': '38', 'VMA-1-16': '39'},
'group_l2n': {'score': 0.6091512680053768, 'VAV-2-1': '12032', 'VAV-2-2': '12033', 'VMA-2-3': '31', 'VMA-2-4': '29', 'VAV-2-5': '12028', 'VMA-2-6': '27', 'VMA-2-7': '30', 'VMA-2-12': '26'},
'group_l2s': {'score': 0.11078681945799929, 'VMA-2-8': '34', 'VAV-2-9': '12035', 'VMA-2-10': '36', 'VMA-2-11': '25', 'VMA-2-13': '23', 'VMA-2-14': '24'}
}
Make it look like this below but in a programmatic way for two separate nested dictionaries named nested_group_map_copy_lows and nested_group_map_copy_high:
nested_group_map_copy_lows = {
'group_l1s': {'score': -0.40303707122802734, 'VMA-1-6': '8', 'VMA-1-8': '6', 'VMA-1-9': '10', 'VMA-1-12': '19', 'VMA-1-13': '20', 'VMA-1-14': '37', 'VMA-1-15': '38', 'VMA-1-16': '39'},
'group_l2s': {'score': 0.11078681945799929, 'VMA-2-8': '34', 'VAV-2-9': '12035', 'VMA-2-10': '36', 'VMA-2-11': '25', 'VMA-2-13': '23', 'VMA-2-14': '24'}
}
nested_group_map_copy_highs = {
'group_l2n': {'score': 0.6091512680053768, 'VAV-2-1': '12032', 'VAV-2-2': '12033', 'VMA-2-3': '31', 'VMA-2-4': '29', 'VAV-2-5': '12028', 'VMA-2-6': '27', 'VMA-2-7': '30', 'VMA-2-12': '26'},
'group_l1n': {'score': 0.12949562072753906, 'VMA-1-1': '14', 'VMA-1-2': '13', 'VMA-1-3': '15', 'VMA-1-4': '11', 'VMA-1-5': '9', 'VMA-1-7': '7', 'VMA-1-10': '21', 'VMA-1-11': '16'},
}
Not really sure how to tackle this, I think I need to use enumerate to create entire new dictionaries but if I try to find highest scores in a separate list scores_
scores_ = []
for i in nested_group_map_original:
scores_.append(nested_group_map_original[i]["score"])
scores_sorted = sorted(scores_, key = float)
Then slice for highest and lowest values:
scores_sorted_highs = scores_sorted[2:]
scores_sorted_lows = scores_sorted[:2]
I am stuck here I dont think del is way to go, any tips greatly appreciated... I know in my code I am not even defining new dictionaries which I think I could do with Python enumerate but not sure how to implement that
for i in nested_group_map_original:
if nested_group_map_original[i]["score"] in scores_sorted_highs:
del nested_group_map_original[i]
This errors out:
RuntimeError: dictionary changed size during iteration
You can sort the keys of the original dictionary according to their corresponding scores, like so:
sorted_keys = sorted(nested_group_map_original, key = lambda x: nested_group_map_original[x]['score'])
You can then split into two different dictionaries according to how many values you want in each. Like in your example of two, you could do the following:
scores_sorted_lows = {k:nested_group_map_original[k] for k in sorted_keys[:2]}
scores_sorted_highs = {k:nested_group_map_original[k] for k in sorted_keys[2:]}
If the dict isn't super huge, then one easy way to do this would just be to construct the list by filtering the map twice using a comprehension:
nested_group_map_low = {k:v for k,v in nested_group_map_original.items() if is_low_score(v["score"])}
nested_group_map_high = {k:v for k,v in nested_group_map_original.items() if not is_low_score(v["score"])}
I have a python list of lists like this
[['CCND1', '67', 'FAS', '99', 'IRAK3', '92', 'ALG14', '86', 'ADRBK1', '10'], ['PTRX', '95', 'CCNA', '33']]
Each alphabetical value is associated with the numeric value , i.e IRAK3 and 92 are associated (92, should appear after IRAK3) and PTRX and 95 are associated (95 should appear after PTRX ). Now , I want to alphabetically sort this list of lists so that the sorted list looks like this:
[['ADRBK1', '10', 'ALG14', '86', 'CCND1', '67', 'FAS', '99', 'IRAK3', '92' ], ['CCNA', '33', 'PTRX', '95' ]]
Note that in the sorted list, the alphabetical values are sorted but again, note that 92, appear after IRAK3 AND 95 appear after PTRX i.e the association is maintained.
How could I do that ?
This is one approach.
Ex:
from itertools import chain
data = [['CCND1', '67', 'FAS', '99', 'IRAK3', '92', 'ALG14', '86', 'ADRBK1', '10'], ['PTRX', '95', 'CCNA', '33']]
#pair elements --> [('CCND1', '67'), ('FAS', '99')....
data = [zip(i[::2], i[1::2]) for i in data]
#sort and flatten
data = [list(chain.from_iterable(sorted(i, key=lambda x: x[0]))) for i in data]
print(data)
"Lists should generally be homogeneous. Use tuples and dictionaries for heterogeneous collections of related data." [1]
One approach would be you arrange them as tuples and then sorting them would also be easier.
mylist = [['CCND1', '67', 'FAS', '99', 'IRAK3', '92', 'ALG14', '86', 'ADRBK1', '10'], ['PTRX', '95', 'CCNA', '33']]
list_of_tuples = []
for l in mylist:
if len(l) % 2 is not 0:
raise ValueError()
list_of_tuples.append([(l[i], l[i+1]) for i in range(0, len(l), 2)])
for l in list_of_tuples:
l.sort(key=lambda tup: tup[0])
print(list_of_tuples)
# [[('ADRBK1', '10'), ('ALG14', '86'), ('CCND1', '67'), ('FAS', '99'), ('IRAK3', '92')], [('CCNA', '33'), ('PTRX', '95')]]
You can try this:
>>> list_ = [['CCND1', '67', 'FAS', '99', 'IRAK3', '92', 'ALG14', '86', 'ADRBK1', '10'], ['PTRX', '95', 'CCNA', '33']]
>>> paired_list = (zip(*[iter(l)]*2) for l in list_)
>>> sorted_list = [list(sum(sorted(l, key=lambda x: x[0]),())) for l in paired_list]
>>> sorted_list
[['ADRBK1', '10', 'ALG14', '86', 'CCND1', '67', 'FAS', '99', 'IRAK3', '92'],
['CCNA', '33', 'PTRX', '95']]
References:
zip(*[iter(iterable)]*n)
sorted
I have used sum to concatenate the list of tuples. However, if you are prepared to use other modules, it is always better to use itertools.chain.from_iterables.
This question already has answers here:
How to sort a list of strings numerically?
(14 answers)
Closed 6 years ago.
I have list of numbers which is in the form of string and I want to sort the numbers in it. How do I sort such numbers in python?
Here is my list.
key_s=['115', '114', '117', '116', '111', '110', '113', '112', '68', '119', '118', '44', '45', '42', '43', '41', '76', '108', '109', '71', '107', '79', '13', '15', '14', '17', '16', '37']
I tried using key_s.sort().It returns None instead of sorted array. I even tried sorted(key_s) which is even not working. So what is the solution to sort it?
Yes, list.sort() sorts in place, and returns None to indicate it is the list itself that has been sorted. The sorted() function returns a new sorted list, leaving the original list unchanged.
Use int as a key:
sorted(key_s, key=int)
This returns a new list, sorted by the numeric value of each string, but leaving the type of the values themselves unchanged.
Without a key, strings are sorted lexicographically instead, comparing character by character. Thus '9' is sorted after '10', because the character '1' comes before '9' in character sets, just like 'a' comes before 'z'.
The key argument lets you apply a Schwartzian_transform, informing the sorting algorithm what to sort by. Each value in the list is sorted according to key(value) (so int(value) here) instead of the original value itself.
Demo:
>>> key_s = ['115', '114', '117', '116', '111', '110', '113', '112', '68', '119', '118', '44', '45', '42', '43', '41', '76', '108', '109', '71', '107', '79', '13', '15', '14', '17', '16', '37']
>>> sorted(key_s, key=int)
['13', '14', '15', '16', '17', '37', '41', '42', '43', '44', '45', '68', '71', '76', '79', '107', '108', '109', '110', '111', '112', '113', '114', '115', '116', '117', '118', '119']
Currently working with a text file that is read into python and then must be made into lists with a list (nested I guess?) So far I've tried using linear searching code but it only checks one of the lists in the nested list:
def populationreader():
with open("PopulationofAnnecy", "r") as in_file:
nested = [line.strip().split(',') for line in in_file][1:]
print nested
This yields the following nested list:
[['Alabama', '126', '79', '17'], ['Alaska', '21', '100', '10'], ['Arizona', '190', '59', '16'], ['Arkansas', '172', '49', '28'], ['California', '4964', '76', '22'] etc …. ]
But it should look something more like:
[[California 4964,76,22],[Texas 3979,62,23],[New York 1858,69,20],[Virginia 1655,60,19]etc …. ]
I've tried using something along the lines of this (pseudo):
for index in range(1,len(alist)):
currentvalue = alist[index]
position = index
while position>0 and alist[position-1]>currentvalue:
alist[position]=alist[position-1]
position = position-1
alist[position]=currentvalue
Trying to do it without using the built in python sort() or sorted() functions but I'm just having trouble sorting things within a list
Once you have your list read in from the file, you can use sort or sorted, but you want to make sure you sort by the second element [1] and make sure to reverse also. Otherwise the default is to sort by the first element of the list (the state name) and alphabetically since it is a string.
l = [['Alabama', '126', '79', '17'],
['Alaska', '21', '100', '10'],
['Arizona', '190', '59', '16'],
['Arkansas', '172', '49', '28'],
['California', '4964', '76', '22'],
['Texas', '3979','62','23'],
['New York', '1858','69','20'],
['Virginia', '1655','60','19']]
sorted(l, key = lambda i: int(i[1]), reverse=True)
Output
[['California', '4964', '76', '22'],
['Texas', '3979', '62', '23'],
['New York', '1858', '69', '20'],
['Virginia', '1655', '60', '19'],
['Arizona', '190', '59', '16'],
['Arkansas', '172', '49', '28'],
['Alabama', '126', '79', '17'],
['Alaska', '21', '100', '10']]