Convert List to Rows - python

What is an efficient way to convert a list into separate elements in python?
I have a dataset that looks like this;
['StudentA','80','94','93']
['StudentB','93','94']
I would like to reshape the data so that each student/score has its own row;
['StudentA','80']
['StudentA','94']
etc...

You could use a list comprehension, like this:
data = ['StudentA','80','94','93']
res = [[data[0], x] for x in data[1:]]
This sets res to [['StudentA', '80'], ['StudentA', '94'], ['StudentA', '93']].

c=['StudentA','80','94','93']
d=[[c[0], p] for p in c[1:]]

This dict comprehension will group you data by student name:
d = {x[0]: x[1:] for x in dataset}
i.e.:
>>> d
{'StudentA': ['80', '94', '93'], 'StudentB': ['93', '94']}
from which you can extract individual pairs with a nested for loop or list comprehension:
>>> [(k, w) for k, v in d.items() for w in v]
[('StudentA', '80'), ('StudentA', '94'), ('StudentA', '93'), ('StudentB', '93'), ('StudentB', '94')]

If it were a list (all_students) containing each of these lines, you could do what you want, by doing :
result = []
for student in all_students:
student_name = student[0]
result.extend([[student_name, value] for value in student[1:]]
print(result)

Couple student with it's respective data using a dictionary.
def to_dict(l):
d = {}
for i in l:
key = i[0]
value = i[1:]
d[key] = value
return d
Sample output:
l = [['studentA', 90, 90],['studentB', 78, 40]]
print to_dict(l)
>>> {'studentB': [78, 40], 'studentA': [90, 90]}
for key, value in d.iteritems():
for i in value:
print key, i
>>> studentB 78
>>> studentB 40
>>> studentA 90
>>> studentA 90

Related

Combining parts of a list inside a list

Given a list like:
[['james',100,200,300],['james',200,300,400], ['charles',200,200,100]]
I need to add the components of the two lists that have the same first index like so:
[['james',300,500,700],['charles',200,200,100]]
Thanks for the answers. Just found out I have to do so without importing any modules. Is there a way to do so? I've tried using for-loops but cannot find out what to index for.
data=[['james',100,200,300],['james',200,300,400], ['charles',200,200,100]]
dic={}
for sample in data:
if sample[0] in dic.keys():
dic[sample[0]] = [x+y for x,y in zip(dic[sample[0]],sample[1:])]
else:
dic[sample[0]] = sample[1:]
data= [[x]+y for x,y in dic.items()]
Explanation: The for loop iterates over all elements of the list. Using the 1st element of each list, we check if 'dic' has this name as a key or not. If yes, we add to previous values of the key else create the key with the values 'sample[1:]'.The last step converts dictionary 'dic' to the desired list
dic = {}
for row in a:
if row[0] in dic:
dic[row[0]] = [sum(n) for n in zip(*[dic[row[0]], row[1:]])]
else:
dic[row[0]] = row[1:]
ans = []
for key in dic:
ans.append([key, *dic[key]])
You can create a dictionary with the names as keys and the subsequent numbers as the value.
Finally you can convert the dictionary to a list of lists.
[sum(n) for n in zip(*[dic[row[0]], row[1:]])] is used to sum up the elements of 2 corresponding lists, refer here : https://stackoverflow.com/a/11280563/10077354
Hmm... no imports sounds like homework. Python is all about re-use. However, just for fun:
data = [['james', 100, 200, 300], ['james', 200, 300, 400], ['charles', 200, 200, 100]]
def combine_lists(data, result=None):
if result is None:
result = []
if data:
return combine_lists(data[1:], _add_sublist(data[0], result))
return result
def _add_sublist(sublist, result):
result_out = []
combined = False
for result_sublist in result:
if sublist[0] == result_sublist[0]:
result_out.append([sublist[0], *[from_elt + into_elt
for from_elt, into_elt in zip(sublist[1:], result_sublist[1:])]])
combined = True
else:
result_out.append(result_sublist)
if not combined:
result_out.append(sublist)
return result_out
Running the function in a shell using your data:
In [4]: combine_lists(data)
Out[4]: [['james', 300, 500, 700], ['charles', 200, 200, 100]]
Make sure you understand the code before handing it in :)
you can use collections.defaultdict:
from collections import defaultdict
l = [['james',100,200,300],['james',200,300,400], ['charles',200,200,100]]
d = defaultdict(list)
for k, *v in l:
d[k].append(v)
[[k, *[sum(e) for e in zip(*v)]] for k, v in d.items()]
output:
[['james', 300, 500, 700], ['charles', 200, 200, 100]]
without importing any module:
l = [['james',100,200,300],['james',200,300,400], ['charles',200,200,100]]
d = {}
for k, *v in l:
d.setdefault(k, []).append(v)
[[k, *[sum(e) for e in zip(*v)]] for k, v in d.items()]
output:
l = [['james',100,200,300],['james',200,300,400], ['charles',200,200,100]]

How can I only parse/split this list with multiple colons in each element? Create dictionary

I have the following Python list:
list1 = ['EW:G:B<<LADHFSSFAFFF', 'CB:E:OWTOWTW', 'PP:E:A,A<F<AF', 'GR:A:OUO-1-XXX-EGD:forthyFive:1:HMJeCXX:7', 'SX:F:-111', 'DS:f:115.5', 'MW:AA:0', 'MA:A:0XT:i:0', 'EY:EE:KJERWEWERKJWE']
I would like to take the entries of this list and create a dictionary of key-values pairs that looks like
dictionary_list1 = {'EW':'G:B<<LADHFSSFAFFF', 'CB':'E:OWTOWTW', 'PP':'E:A,A<F<AF', 'GR':'A:OUO-1-XXX-EGD:forthyFive:1:HMJeCXX:7', 'SX':'F:-111', 'DS':'f:115.5', 'MW':'AA:0', 'MA':'A:0XT:i:0', 'EW':'EE:KJERWEWERKJWE'}
How does one parse/split the list above list1 to do this? My first instinct was to try try1 = list1.split(":"), but then I think it is impossible to retrieve the "key" for this list, as there are multiple colons :
What is the most pythonic way to do this?
You can specify a maximum number of times to split with the second argument to split.
list1 = ['EW:G:B<<LADHFSSFAFFF', 'CB:E:OWTOWTW', 'PP:E:A,A<F<AF', 'GR:A:OUO-1-XXX-EGD:forthyFive:1:HMJeCXX:7', 'SX:F:-111', 'DS:f:115.5', 'MW:AA:0', 'MA:A:0XT:i:0', 'EW:EE:KJERWEWERKJWE']
d = dict(item.split(':', 1) for item in list1)
Result:
>>> import pprint
>>> pprint.pprint(d)
{'CB': 'E:OWTOWTW',
'DS': 'f:115.5',
'EW': 'EE:KJERWEWERKJWE',
'GR': 'A:OUO-1-XXX-EGD:forthyFive:1:HMJeCXX:7',
'MA': 'A:0XT:i:0',
'MW': 'AA:0',
'PP': 'E:A,A<F<AF',
'SX': 'F:-111'}
If you'd like to keep track of values for non-unique keys, like 'EW:G:B<<LADHFSSFAFFF' and 'EW:EE:KJERWEWERKJWE', you could add keys to a collections.defaultdict:
import collections
d = collections.defaultdict(list)
for item in list1:
k,v = item.split(':', 1)
d[k].append(v)
Result:
>>> pprint.pprint(d)
{'CB': ['E:OWTOWTW'],
'DS': ['f:115.5'],
'EW': ['G:B<<LADHFSSFAFFF', 'EE:KJERWEWERKJWE'],
'GR': ['A:OUO-1-XXX-EGD:forthyFive:1:HMJeCXX:7'],
'MA': ['A:0XT:i:0'],
'MW': ['AA:0'],
'PP': ['E:A,A<F<AF'],
'SX': ['F:-111']}
You can also use str.partition
list1 = ['EW:G:B<<LADHFSSFAFFF', 'CB:E:OWTOWTW', 'PP:E:A,A<F<AF', 'GR:A:OUO-1-XXX-EGD:forthyFive:1:HMJeCXX:7', 'SX:F:-111', 'DS:f:115.5', 'MW:AA:0', 'MA:A:0XT:i:0', 'EW:EE:KJERWEWERKJWE']
d = dict([t for t in x.partition(':') if t!=':'] for x in list1)
# or more simply as TigerhawkT3 mentioned in the comment
d = dict(x.partition(':')[::2] for x in list1)
for k, v in d.items():
print('{}: {}'.format(k, v))
Output:
MW: AA:0
CB: E:OWTOWTW
GR: A:OUO-1-XXX-EGD:forthyFive:1:HMJeCXX:7
PP: E:A,A<F<AF
EW: EE:KJERWEWERKJWE
SX: F:-111
DS: f:115.5
MA: A:0XT:i:0

removing duplicates from a list python

I have two lists:
list1 = [IM12345, IM12346, IM12347, IM12348]
list2 = [ID300, ID404, ID300, ID601]
list2 associates with the corresponding list1 values. list1 has unique values where as list2 has duplicates.
I want to make list2 unique corresponding associated value will add in the that list2 value.
Dict= {ID300: {IM12345, IM12347}, ID404: IM12346, ID601: IM12348}
Above pattern can be in list, set or dictionary.
Which algorithm in python should I use to get the above result?
You could try collections.defaultdict:
from collections import defaultdict
d = defaultdict(set)
list1 = ['IM12345', 'IM12346', 'IM12347', 'IM12348']
list2 = ['ID300', 'ID404', 'ID300', 'ID601']
for key, value in zip(list2, list1):
d[key].add(value)
Demo:
>>> d
defaultdict(<class 'set'>, {'ID300': {'IM12345', 'IM12347'}, 'ID404': {'IM12346'}, 'ID601': {'IM12348'}})
>>>
>>>
>>> for i, j in d.items():
... print(i, j)
...
...
ID601 {'IM12348'}
ID300 {'IM12345', 'IM12347'}
ID404 {'IM12346'}
You can create a dict to save the dataset
list1 = ["IM12345", "IM12346", "IM12347", "IM12348"]
list2 = ["ID300", "ID404", "ID300", "ID601"]
dictResult=dict()
i=0
for item in list2:
print item
if dictResult.has_key(item):
dictResult[item].append(list1[i])
else:
dictResult[item]=[list1[i]]
i=i+1
print dictResult
Result:
{'ID404': ['IM12346'], 'ID300': ['IM12345', 'IM12347'], 'ID601': ['IM12348']}
Might not completely be a pythonic way but - here it goes:
Map the input:
map = dict(zip(list1, list2))
Now you can do an inverse mapping:
inv_map = {}
for k, v in map.iteritems():
inv_map[v] = inv_map.get(v, [])
inv_map[v].append(k)
Result for the example above:
>>> inv_map
{'ID404': ['IM12346'], 'ID300': ['IM12345', 'IM12347'], 'ID601': ['IM12348']}
Another way of doing it could be with list operations.
yourList = ["1","2","3","4","1","2"]
newList = []
for f in yourList:
if f not in newList:
newList.append(f)
Simple solution
from collections import defaultdict
list1 = ['IM12345', 'IM12346', 'IM12347', 'IM12348']
list2 = ['ID300', 'ID404', 'ID300', 'ID601']
d = defaultdict(list)
for n in range(len(list2)):
d[list2[n]].append(list1[n])
print d.items()
Result:
[('ID404', ['IM12346']), ('ID300', ['IM12345', 'IM12347']), ('ID601', ['IM12348'])]
Python2.7 Documentation----defaultdict

Refer a value from a key which is in the form tuple of multiple elements

dic = {('UUU','UUC'):'F',('GUU','GUC','GUA','GUG'):'V'}
L = ['UUU', 'GUG', 'GUU']
As you see each elements of list(L) are in dictionary as keys. Now i want to replace each elements of L by its corresponding values. Output would be:
output = ['F','V']
How can i do that?
One way would be to decompose the keys into individual elements, and create a new dict from those:
new_dic = {}
for k, v in dic.items():
for sub_k in k:
new_dic[sub_k] = v
Now it's a simple matter of looping through the list:
output = [new_dic[i] for i in L]
and you can de-duplicate with set:
output = list(set(output))
Using list compression:
In [1]: dic = {('UUU','UUC'):'F',('GUU','GUC','GUA','GUG'):'V'}
In [2]: L = ['UUU', 'GUG', 'GUU']
In [3]: list(set([v for k,v in dic.items() for x in L if x in k]))
Out [3]: ['V', 'F']

Combine Python dictionaries that have the same Key name

I have two separate Python List that have common key names in their respective dictionary. The second list called recordList has multiple dictionaries with the same key name that I want to append the first list clientList. Here are examples lists:
clientList = [{'client1': ['c1','f1']}, {'client2': ['c2','f2']}]
recordList = [{'client1': {'rec_1':['t1','s1']}}, {'client1': {'rec_2':['t2','s2']}}]
So the end result would be something like this so the records are now in a new list of multiple dictionaries within the clientList.
clientList = [{'client1': [['c1','f1'], [{'rec_1':['t1','s1']},{'rec_2':['t2','s2']}]]}, {'client2': [['c2','f2']]}]
Seems simple enough but I'm struggling to find a way to iterate both of these dictionaries using variables to find where they match.
When you are sure, that the key names are equal in both dictionaries:
clientlist = dict([(k, [clientList[k], recordlist[k]]) for k in clientList])
like here:
>>> a = {1:1,2:2,3:3}
>>> b = {1:11,2:12,3:13}
>>> c = dict([(k,[a[k],b[k]]) for k in a])
>>> c
{1: [1, 11], 2: [2, 12], 3: [3, 13]}
Assuming you want a list of values that correspond to each key in the two lists, try this as a start:
from pprint import pprint
clientList = [{'client1': ['c1','f1']}, {'client2': ['c2','f2']}]
recordList = [{'client1': {'rec_1':['t1','s1']}}, {'client1': {'rec_2':['t2','s2']}}]
clientList.extend(recordList)
outputList = {}
for rec in clientList:
k = rec.keys()[0]
v = rec.values()[0]
if k in outputList:
outputList[k].append(v)
else:
outputList[k] = [v,]
pprint(outputList)
It will produce this:
{'client1': [['c1', 'f1'], {'rec_1': ['t1', 's1']}, {'rec_2': ['t2', 's2']}],
'client2': [['c2', 'f2']]}
This could work but I am not sure I understand the rules of your data structure.
# join all the dicts for better lookup and update
clientDict = {}
for d in clientList:
for k, v in d.items():
clientDict[k] = clientDict.get(k, []) + v
recordDict = {}
for d in recordList:
for k, v in d.items():
recordDict[k] = recordDict.get(k, []) + [v]
for k, v in recordDict.items():
clientDict[k] = [clientDict[k]] + v
# I don't know why you need a list of one-key dicts but here it is
clientList = [dict([(k, v)]) for k, v in clientDict.items()]
With the sample data you provided this gives the result you wanted, hope it helps.

Categories

Resources