I have 3 lists with different lengths. They are made like this:
final_list = [[1230, 0], [1231,0],[1232,0], [1233, 0], [1234, 0]]
list2 = [[1232, 20], [1233, 30]]
list3 = [[1230, 10], [1231,20],[1232,40]]
What I want to obtain the final_list like this:
final_list = [[1230, 10], [1231,20],[1232,60], [1233, 30], [1234, 0]]
(If, considering each element of list2 and list3, its first value is equal to one of the first elements of the final list, then the corresponding element of the final list has to have the second value equal to the sum of the elements found.)
Not a clean solution, but easy to grasp and might save your day.
f = {}
dcts = map(lambda l: dict([l]), list2+list3)
for dct in dcts:
for k in dct.iterkeys():
f[k] = w.get(k, 0) + d[k]
final_list = map(list, f.items())
however, if you are familiar with itertools
import groupby from itertools
merged = list2+list3
final_list = []
for key, group in groupby(merged, key = lambda e: e[0]):
final_list.append([key, sum(j for i, j in group)])
or a oneliner
[[k, sum(j for i, j in g)] for k, g in groupby(list3+list2, key = lambda e: e[0])]
I created a temp_list and append all three lists to it.
create a dictionary dic and loop through temp_list to sum up each tuple base on the key.
then I turn the dic back into a list and sort it.
I admit this is not the most efficient way to do this. but it is a solution.
temp_list = []
temp_list.append(final_list)
temp_list.append(list2)
temp_list.append(list3)
dic = {}
for lst in temp_list:
for tp in lst:
if tp[0] in dic:
dic[tp[0]] = dic[tp[0]] + tp[1]
else:
dic[tp[0]] = tp[1]
result = []
for key, value in dic.iteritems():
temp = [key,value]
result.append(temp)
result.sort()
result:
[(1230, 10), (1231, 20), (1232, 60), (1233, 30), (1234, 0)]
Related
So I got this list of lists:
lst = [[0,1],2,[3]]
and I got a list of tuples:
lst_2 = [("x1","y1"),("x2","y2"), ("x3","y3"), ("x4","y4")]
I want to replace values inside lst with the index 0 value of each of the tuples in lst_2, and the tuple taken depends on the numerical value in lst. So it becomes:
lst = [["x1","x2"], "x3", ["x4"]]
Please don't roast me thanks so much
Try this:
lst = [[0,1],2,[3]]
lst_2 = [("x1","y1"),("x2","y2"), ("x3","y3"), ("x4","y4")]
res = []
for l in lst:
if isinstance(l, list):
res += [[lst_2[i][0] for i in l]]
else:
res += [lst_2[l][0]]
print(res)
Or with List Comprehensions:
res = [[lst_2[i][0] for i in l] if isinstance(l, list) else lst_2[l][0] for l in lst]
[['x1', 'x2'], 'x3', ['x4']]
You could use recursion to allow lst to have deeper levels of nesting:
def produce(template, data):
return [
produce(nested, data) for nested in template
] if isinstance(template, list) else data[template][0]
# Example
lst = [[0,[1]],2,[3]]
lst_2 = [("x1","y1"),("x2","y2"), ("x3","y3"), ("x4","y4")]
result = produce(lst, lst_2)
I have 2 lists
mainlist=[['RD-12',12,'a'],['RD-13',45,'c'],['RD-15',50,'e']] and
sublist=[['RD-12',67],['RD-15',65]]
if i join both the list based on 1st element condition by using below code
def combinelist(mainlist,sublist):
dict1 = { e[0]:e[1:] for e in mainlist }
for e in sublist:
try:
dict1[e[0]].extend(e[1:])
except:
pass
result = [ [k] + v for k, v in dict1.items() ]
return result
Its results in like below
[['RD-12',12,'a',67],['RD-13',45,'c',],['RD-15',50,'e',65]]
as their is no element in for 'RD-13' in sublist, i want to empty string on that.
The final output should be
[['RD-12',12,'a',67],['RD-13',45,'c'," "],['RD-15',50,'e',65]]
Please help me.
Your problem can be solved using a while loop to adjust the length of your sublists until it matches the length of the longest sublist by appending the wanted string.
for list in result:
while len(list) < max(len(l) for l in result):
list.append(" ")
You could just go through the result list and check where the total number of your elements is 2 instead of 3.
for list in lists:
if len(list) == 2:
list.append(" ")
UPDATE:
If there are more items in the sublist, just subtract the lists containing the 'keys' of your lists, and then add the desired string.
def combinelist(mainlist,sublist):
dict1 = { e[0]:e[1:] for e in mainlist }
list2 = [e[0] for e in sublist]
for e in sublist:
try:
dict1[e[0]].extend(e[1:])
except:
pass
for e in dict1.keys() - list2:
dict1[e].append(" ")
result = [[k] + v for k, v in dict1.items()]
return result
You can try something like this:
mainlist=[['RD-12',12],['RD-13',45],['RD-15',50]]
sublist=[['RD-12',67],['RD-15',65]]
empty_val = ''
# Lists to dictionaries
maindict = dict(mainlist)
subdict = dict(sublist)
result = []
# go through all keys
for k in list(set(list(maindict.keys()) + list(subdict.keys()))):
# pick the value from each key or a default alternative
result.append([k, maindict.pop(k, empty_val), subdict.pop(k, empty_val)])
# sort by the key
result = sorted(result, key=lambda x: x[0])
You can set up your empty value to whatever you need.
UPDATE
Following the new conditions, it would look like this:
mainlist=[['RD-12',12,'a'], ['RD-13',45,'c'], ['RD-15',50,'e']]
sublist=[['RD-12',67], ['RD-15',65]]
maindict = {a:[b, c] for a, b, c in mainlist}
subdict = dict(sublist)
result = []
for k in list(set(list(maindict.keys()) + list(subdict.keys()))):
result.append([k, ])
result[-1].extend(maindict.pop(k, ' '))
result[-1].append(subdict.pop(k, ' '))
sorted(result, key=lambda x: x[0])
Another option is to convert the sublist to a dict, so items are easily and rapidly accessible.
sublist_dict = dict(sublist)
So you can do (it modifies the mainlist):
for i, e in enumerate(mainlist):
data: mainlist[i].append(sublist_dict.get(e[0], ""))
#=> [['RD-12', 12, 'a', 67], ['RD-13', 45, 'c', ''], ['RD-15', 50, 'e', 65]]
Or a one liner list comprehension (it produces a new list):
[ e + [sublist_dict.get(e[0], "")] for e in mainlist ]
If you want to skip the missing element:
for i, e in enumerate(mainlist):
data = sublist_dict.get(e[0])
if data: mainlist[i].append(data)
print(mainlist)
#=> [['RD-12', 12, 'a', 67], ['RD-13', 45, 'c'], ['RD-15', 50, 'e', 65]]
So, I have two lists whose integer elements need to be added.
nested_lst_1 = [[6],[7],[8,9]]
lst = [1,2,3]
I need to add them such that every element in the nested list, will be added to its corresponding integer in 'lst' to obtain another nested list.
nested_list_2 = [[6 + 1],[7 + 2],[8 + 3,9 + 3]]
or
nested_list_2 = [[7],[9],[11,12]]
Then, I need to use the integers from nested_list_1 and nested_list_2 as indices to extract a substring from a string.
nested_list_1 = [[6],[7],[8,9]] *obtained above*
nested_list_2 = [[7],[9],[11,12]] *obtained above*
string = 'AGTCATCGTACGATCATCGAAGCTAGCAGCATGAC'
string[6:7] = 'CG'
string[7:9] = 'GTA'
string[8:11] = 'TACG'
string[9:12] = 'ACGA'
Then, I need to create a nested list of the substrings obtained:
nested_list_substrings = [['CG'],['GTA'],['TACG','ACGA']]
Finally, I need to use these substrings as key values in a dictionary which also possesses keys of type string.
keys = ['GG', 'GTT', 'TCGG']
nested_list_substrings = [['CG'],['GTA'],['TACG','ACGA']]
DNA_mutDNA = {'GG':['CG'], 'GTT':['GTA'], 'TCGG':['TACG','ACGA']}
I understand that this is a multi-step problem, but if you could assist in any way, I really appreciate it.
Assuming you don't need the intermediate variables, you can do all this with a dictionary comprehension:
a = [[6],[7],[8,9]]
b = [1,2,3]
keys = ['GG', 'GTT', 'TCGG']
s = 'AGTCATCGTACGATCATCGAAGCTAGCAGCATGAC'
DNA_mutDNA = {k: [s[start:start+length+1] for start in starts]
for k, starts, length in zip(keys, a, b)}
You can produce the substring list directly with a nested list comprehension, nested_lst_2 isn't necessary.
nested_lst_1 = [[6],[7],[8,9]]
lst = [1,2,3]
string = 'AGTCATCGTACGATCATCGAAGCTAGCAGCATGAC'
keys = ['GG', 'GTT', 'TCGG']
substrings = [[string[v:i+v+1] for v in u] for i, u in zip(lst, nested_lst_1)]
print(substrings)
DNA_mutDNA = dict(zip(keys, substrings))
print(DNA_mutDNA)
output
[['CG'], ['GTA'], ['TACG', 'ACGA']]
{'GG': ['CG'], 'GTT': ['GTA'], 'TCGG': ['TACG', 'ACGA']}
In[2]: nested_lst_1 = [[6],[7],[8,9]]
...: lst = [1,2,3]
...: string = 'AGTCATCGTACGATCATCGAAGCTAGCAGCATGAC'
...: keys = ['GG', 'GTT', 'TCGG']
In[3]: nested_lst_2 = [[elem + b for elem in a] for a, b in zip(nested_lst_1, lst)]
In[4]: nested_list_substrings = []
...: for a, b in zip(nested_lst_1, nested_lst_2):
...: nested_list_substrings.append([string[c:d + 1] for c, d in zip(a, b)])
...:
In[5]: {k: v for k, v in zip(keys, nested_list_substrings)}
Out[5]: {'GG': ['CG'], 'GTT': ['GTA'], 'TCGG': ['TACG', 'ACGA']}
Surely not the most readable way to do it, here is a bit of functional style fun:
nested_lst_1 = [[6], [7], [8,9]]
lst = [1, 2, 3]
nested_lst_2 = list(map(
list,
map(map, map(lambda n: (lambda x: n+x), lst), nested_lst_1)))
nested_lst_2
Result looks as expected:
[[7], [9], [11, 12]]
Then:
from itertools import starmap
from operator import itemgetter
make_slices = lambda l1, l2: starmap(slice, zip(l1, map(lambda n: n+1, l2)))
string = 'AGTCATCGTACGATCATCGAAGCTAGCAGCATGAC'
get_slice = lambda s: itemgetter(s)(string)
nested_list_substrings = list(map(
lambda slices: list(map(get_slice, slices)),
starmap(make_slices, zip(nested_lst_1, nested_lst_2))))
nested_list_substrings
Result:
[['CG'], ['GTA'], ['TACG', 'ACGA']]
And finally:
keys = ['GG', 'GTT', 'TCGG']
DNA_mutDNA = dict(zip(keys, nested_list_substrings))
DNA_mutDNA
Final result:
{'GG': ['CG'], 'GTT': ['GTA'], 'TCGG': ['TACG', 'ACGA']}
I would like to generate a list of unique Ids by only keeping the list that has the minimum value in element 2.
For example, given the list:
list1 = [['Id1', 1, 40],['Id1', 2, 30],['Id2', 10,40]]`
Expected output:
[['Id1', 1, 40],['Id2', 10,40]]
Here's my working example, but it's pretty clunky. I think it could probably be done with a single list comprehension.
list1 = [['Id1', 1, 40],['Id1', 2, 30],['Id2', 10,40]]
unique_list = list(set([x[0] for x in list1]))
unique_list = [[x] for x in unique_list]
for x in unique_list:
id = x[0]
min_val = min([y[1:] for y in list1 if y[0] == id])
x.extend(min_val )
print unique_list
You can use itertools.groupby to group by the first element in the sublists, the you can get the min with a key argument to sort by the remaining elements in the sublist.
>>> from itertools import groupby
[min(list(g), key = lambda i: i[1:]) for k, g in groupby(list1, lambda i: i[0])]
[['Id1', 1, 40], ['Id2', 10, 40]]
A very naive approach but easily understandable.
list1 = [['Id1', 1, 40],['Id1', 2, 30],['Id2', 10,40]]
unique_list = []
for list_element in list1:
appendable = True
for temp_list in unique_list:
if list_element[0] == temp_list[0]:
if temp_list[1] < list_element[1]:
appendable = False
else:
unique_list.remove(temp_list)
if appendable == True:
unique_list.append(list_element)
unique_list.sort()
print unique_list
Say you have a dictionary listing the indices where each unique value appear. For example say you alphabet is just a and b then this dictionary will look something like: d = {'a': [1, 2, 6], 'b': [3, 7]}. I would like to convert it to the raw list which shows at the right index the right value, such that in the last example, l = ['a','a','b',None,None,'a',b']. I prefer an easy small solution rather than one which has tedious for loops. Thank!
Obviously doing this without for loops is a terrible idea, because the easiest way is (it's not perfect, but it does the job):
r = {}
for key, value in d.items():
for element in value:
r[element] = key
l = [r.get(i) for i in xrange(1, max(r) + 1)]
But if you REALLY want to know how to do this without any for then have a look:
m = {}
i = 0
d_keys = d.keys()
max_value = 0
while i < len(d):
d_i = d[d_keys[i]]
j = 0
while j < len(d_i):
d_i_j = d_i[j]
if max_value < d_i_j:
max_value = d_i_j
m[d_i_j] = d_keys[i]
j += 1
i += 1
l = []
i = 1
while i <= max_value:
l.append(m.get(i))
i += 1
It's quite easy, isn't it?
I don't know why you need that, but here is a dirty answer, without loops.
d = {'a': [1, 2, 6], 'b': [3, 7]}
map(lambda x: x[0] if x else None, map(lambda x: filter(lambda l: x in d[l], d), range(1, max(reduce(lambda x, y: x+y, map(lambda x:d[x], d)))+1)))
d.keys()
keys()
Return a copy of the dictionary’s list of keys. See the note for dict.items()
from Python Docs