I want to group by my_list based on another list keys as follows:
my_list = ['apple_2010', 'banana_2010', 'carrot_2010', 'dog_2011', 'eye_2011', 'fig_2011']
keys = ['2010','2010','2010','2011','2011','2011']
for x,y in zip(my_list,keys):
???
The expected answer is:
answer = [['apple_2010', 'banana_2010', 'carrot_2010'],
['dog_2011', 'eye_2011', 'fig_2011']]
>>> my_list = ['apple_2010', 'banana_2010', 'carrot_2010', 'dog_2011', 'eye_2011', 'fig_2011']
>>> keys = ['2010','2010','2010','2011','2011','2011']
>>> print [[value for value in my_list if key in value] for key in set(keys)]
[['dog_2011', 'eye_2011', 'fig_2011'], ['apple_2010', 'banana_2010', 'carrot_2010']]
Related
In short what I need to be done is for each element from a list get the respective value from a dictionary list and replace it
For instance... For the following input lists
list1 = ['gui', 'guigui', 'guiguigguuii']
list2 = ['gui', 'gui', 'gui', 'gui', 'gui', 'gui']
I should look for in those dictionaries list
dictlist1 = [{'gui': 'ya'}, {'guigui': 'lyub'}, {'guiguigguuii': 'htr'}]
dictlist2 = [{'gui': 'asdf'}]
and it should output
output1 = ['ya', 'lyub', 'htr']
output2 = ['asdf', 'asdf', 'asdf', 'asdf', 'asdf', 'asdf']
I have written a code... However it is not working for the second data sample
print(' '.join([item for sublist in [[value for key, value in d.items()] for d in lista] for item in sublist]))
Here, sorry if it's a bit long but, I think using this template your could figure something out.
list1 = ['gui', 'guigui', 'guiguigguuii']
replace = [{'gui': 'ya'}, {'guigui': 'lyub'}, {'guiguigguuii': 'htr'}]
newList = []
#iterate through list1
for words in list1:
count = 0
#iterate through replaces dicts
for dicts in replace:
#Check if any word in list1 can be replaced
if words == list(dicts.keys())[0]:newList.append(dicts[list(dicts.keys())[0]])
count += 1
print(newList)
output
['ya', 'lyub', 'htr']
I have a nested dictionary with list of values, I want to have
- the maximum index wise value between two lists
- the 'id' for each max value (by id I mean from which list is the value coming and what index it is).
I already have the index wise max value between the two lists, what I need with is the 'id'.
#create dictionary:
test = {}
test['A'] = {}
test['A']['number'] = [2,2,3]
test['A']['id'] = ['x','y','z']
test['B'] = {}
test['B']['number'] = [1,3,2]
test['B']['id'] = ['a','b','c']
#this the maximum index-wise value between the two lists
max_list = [max(*l) for l in zip(test['A']['number'], test['B']['number'])]
print(max_list)
What I would like is another list with the following:
['x','b','z']
make an inner zip of id and number so we know which id belongs to which number,
then use max with a custom key function (by number), then split them:
test = {}
test['A'] = {}
test['A']['number'] = [2,2,3]
test['A']['id'] = ['x','y','z']
test['B'] = {}
test['B']['number'] = [1,3,2]
test['B']['id'] = ['a','b','c']
tuple_list = [max(*l, key=lambda t: t[1]) for l in zip(zip(test['A']['id'],test['A']['number']), zip(test['B']['id'],test['B']['number']))]
max_num_list = [t[1] for t in tuple_list]
max_id_list = [t[0] for t in tuple_list]
print(max_num_list)
print(max_id_list)
Output:
[2, 3, 3]
['x', 'b', 'z']
I have a list as below
tlist=[(‘abc’,HYD,’user1’), (‘xyz’,’SNG’,’user2’), (‘pppp’,’US’,’user3’), (‘qq’,’HK’,’user4’)]
I want to display the second field tuple of provided first field of tuple.
Ex:
tlist(‘xyz’)
SNG
Is there way to get it?
A tuple doesn't have a hash table lookup like a dictionary, so you will need to loop through it in sequence until you find it:
def find_in_tuple(tlist, search_term):
for x, y, z in tlist:
if x == search_term:
return y
print(find_in_tuple(tlist, 'xyz')) # prints 'SNG'
If you plan to do this multiple times, you definitely want to convert to a dictionary. I would recommend making the first element of the tuple the key and then the other two the values for that key. You can do this very easily using a dictionary comprehension.
>>> tlist_dict = { k: (x, y) for k, x, y in tlist } # Python 3: { k: v for k, *v in tlist }
>>> tlist_dict
{'qq': ['HK', 'user4'], 'xyz': ['SNG', 'user2'], 'abc': ['HYD', 'user1'], 'pppp': ['US', 'user3']}
You can then select the second element as follows:
>>> tlist_dict['xyz'][0]
'SNG'
If there would be multiple tuples with xyz as a first item, use the following simple approach(with modified example):
tlist = [('abc','HYD','user1'), ('xyz','SNG','user2'), ('pppp','US','user3'), ('xyz','HK','user4')]
second_fields = [f[1] for f in tlist if f[0] == 'xyz']
print(second_fields) # ['SNG', 'HK']
I'm trying to get the matching IDs and store the data into one list. I have a list of dictionaries:
list = [
{'id':'123','name':'Jason','location': 'McHale'},
{'id':'432','name':'Tom','location': 'Sydney'},
{'id':'123','name':'Jason','location':'Tompson Hall'}
]
Expected output would be something like
# {'id':'123','name':'Jason','location': ['McHale', 'Tompson Hall']},
# {'id':'432','name':'Tom','location': 'Sydney'},
How can I get matching data based on dict ID value? I've tried:
for item in mylist:
list2 = []
row = any(list['id'] == list.id for id in list)
list2.append(row)
This doesn't work (it throws: TypeError: tuple indices must be integers or slices, not str). How can I get all items with the same ID and store into one dict?
First, you're iterating through the list of dictionaries in your for loop, but never referencing the dictionaries, which you're storing in item. I think when you wrote list[id] you mean item[id].
Second, any() returns a boolean (true or false), which isn't what you want. Instead, maybe try row = [dic for dic in list if dic['id'] == item['id']]
Third, if you define list2 within your for loop, it will go away every iteration. Move list2 = [] before the for loop.
That should give you a good start. Remember that row is just a list of all dictionaries that have the same id.
I would use kdopen's approach along with a merging method after converting the dictionary entries I expect to become lists into lists. Of course if you want to avoid redundancy then make them sets.
mylist = [
{'id':'123','name':['Jason'],'location': ['McHale']},
{'id':'432','name':['Tom'],'location': ['Sydney']},
{'id':'123','name':['Jason'],'location':['Tompson Hall']}
]
def merge(mylist,ID):
matches = [d for d in mylist if d['id']== ID]
shell = {'id':ID,'name':[],'location':[]}
for m in matches:
shell['name']+=m['name']
shell['location']+=m['location']
mylist.remove(m)
mylist.append(shell)
return mylist
updated_list = merge(mylist,'123')
Given this input
mylist = [
{'id':'123','name':'Jason','location': 'McHale'},
{'id':'432','name':'Tom','location': 'Sydney'},
{'id':'123','name':'Jason','location':'Tompson Hall'}
]
You can just extract it with a comprehension
matched = [d for d in mylist if d['id'] == '123']
Then you want to merge the locations. Assuming matched is not empty
final = matched[0]
final['location'] = [d['location'] for d in matched]
Here it is in the interpreter
In [1]: mylist = [
...: {'id':'123','name':'Jason','location': 'McHale'},
...: {'id':'432','name':'Tom','location': 'Sydney'},
...: {'id':'123','name':'Jason','location':'Tompson Hall'}
...: ]
In [2]: matched = [d for d in mylist if d['id'] == '123']
In [3]: final=matched[0]
In [4]: final['location'] = [d['location'] for d in matched]
In [5]: final
Out[5]: {'id': '123', 'location': ['McHale', 'Tompson Hall'], 'name': 'Jason'}
Obviously, you'd want to replace '123' with a variable holding the desired id value.
Wrapping it all up in a function:
def merge_all(df):
ids = {d['id'] for d in df}
result = []
for id in ids:
matches = [d for d in df if d['id'] == id]
combined = matches[0]
combined['location'] = [d['location'] for d in matches]
result.append(combined)
return result
Also, please don't use list as a variable name. It shadows the builtin list class.
I am having two lists as follows:
list_1
['A-1','A-1','A-1','A-2','A-2','A-3']
list_2
['iPad','iPod','iPhone','Windows','X-box','Kindle']
I would like to split the list_2 based on the index values in list_1. For instance,
list_a1
['iPad','iPod','iPhone']
list_a2
['Windows','X-box']
list_a3
['Kindle']
I know index method, but it needs the value to be matched to be passed along with. In this case, I would like to dynamically find the indexes of the values in list_1 with the same value. Is this possible? Any tips/hints would be deeply appreciated.
Thanks.
There are a few ways to do this.
I'd do it by using zip and groupby.
First:
>>> list(zip(list_1, list_2))
[('A-1', 'iPad'),
('A-1', 'iPod'),
('A-1', 'iPhone'),
('A-2', 'Windows'),
('A-2', 'X-box'),
('A-3', 'Kindle')]
Now:
>>> import itertools, operator
>>> [(key, list(group)) for key, group in
... itertools.groupby(zip(list_1, list_2), operator.itemgetter(0))]
[('A-1', [('A-1', 'iPad'), ('A-1', 'iPod'), ('A-1', 'iPhone')]),
('A-2', [('A-2', 'Windows'), ('A-2', 'X-box')]),
('A-3', [('A-3', 'Kindle')])]
So, you just want each group, ignoring the key, and you only want the second element of each element in the group. You can get the second element of each group with another comprehension, or just by unzipping:
>>> [list(zip(*group))[1] for key, group in
... itertools.groupby(zip(list_1, list_2), operator.itemgetter(0))]
[('iPad', 'iPod', 'iPhone'), ('Windows', 'X-box'), ('Kindle',)]
I would personally find this more readable as a sequence of separate iterator transformations than as one long expression. Taken to the extreme:
>>> ziplists = zip(list_1, list_2)
>>> pairs = itertools.groupby(ziplists, operator.itemgetter(0))
>>> groups = (group for key, group in pairs)
>>> values = (zip(*group)[1] for group in groups)
>>> [list(value) for value in values]
… but a happy medium of maybe 2 or 3 lines is usually better than either extreme.
Usually I'm the one rushing to a groupby solution ;^) but here I'll go the other way and manually insert into an OrderedDict:
list_1 = ['A-1','A-1','A-1','A-2','A-2','A-3']
list_2 = ['iPad','iPod','iPhone','Windows','X-box','Kindle']
from collections import OrderedDict
d = OrderedDict()
for code, product in zip(list_1, list_2):
d.setdefault(code, []).append(product)
produces a d looking like
>>> d
OrderedDict([('A-1', ['iPad', 'iPod', 'iPhone']),
('A-2', ['Windows', 'X-box']), ('A-3', ['Kindle'])])
with easy access:
>>> d["A-2"]
['Windows', 'X-box']
and we can get the list-of-lists in list_1 order using .values():
>>> d.values()
[['iPad', 'iPod', 'iPhone'], ['Windows', 'X-box'], ['Kindle']]
If you've noticed that no one is telling you how to make a bunch of independent lists with names like list_a1 and so on-- that's because that's a bad idea. You want to keep the data together in something which you can (at a minimum) iterate over easily, and both dictionaries and list of lists qualify.
Maybe something like this?
#!/usr/local/cpython-3.3/bin/python
import pprint
import collections
def main():
list_1 = ['A-1','A-1','A-1','A-2','A-2','A-3']
list_2 = ['iPad','iPod','iPhone','Windows','X-box','Kindle']
result = collections.defaultdict(list)
for list_1_element, list_2_element in zip(list_1, list_2):
result[list_1_element].append(list_2_element)
pprint.pprint(result)
main()
Using itertools.izip_longest and itertools.groupby:
>>> from itertools import groupby, izip_longest
>>> inds = [next(g)[0] for k, g in groupby(enumerate(list_1), key=lambda x:x[1])]
First group items of list_1 and find the starting index of each group:
>>> inds
[0, 3, 5]
Now use slicing and izip_longest as we need pairs list_2[0:3], list_2[3:5], list_2[5:]:
>>> [list_2[x:y] for x, y in izip_longest(inds, inds[1:])]
[['iPad', 'iPod', 'iPhone'], ['Windows', 'X-box'], ['Kindle']]
To get a list of dicts you can something like:
>>> inds = [next(g) for k, g in groupby(enumerate(list_1), key=lambda x:x[1])]
>>> {k: list_2[ind1: ind2[0]] for (ind1, k), ind2 in
zip_longest(inds, inds[1:], fillvalue=[None])}
{'A-1': ['iPad', 'iPod', 'iPhone'], 'A-3': ['Kindle'], 'A-2': ['Windows', 'X-box']}
You could do this if you want simple code, it's not pretty, but gets the job done.
list_1 = ['A-1','A-1','A-1','A-2','A-2','A-3']
list_2 = ['iPad','iPod','iPhone','Windows','X-box','Kindle']
list_1a = []
list_1b = []
list_1c = []
place = 0
for i in list_1[::1]:
if list_1[place] == 'A-1':
list_1a.append(list_2[place])
elif list_1[place] == 'A-2':
list_1b.append(list_2[place])
else:
list_1c.append(list_2[place])
place += 1