0

So I have a list of tuples such as this:

atten = [('14', datetime.datetime(2019, 11, 20, 16, 37), 255, 1), ('901', datetime.datetime(2019, 11, 20, 16, 39, 56), 255, 1), ('901', datetime.datetime(2019, 11, 20, 16, 49, 10), 255, 1), ('14', datetime.datetime(2019, 11, 20, 16, 50, 7), 255, 1), ('901', datetime.datetime(2019, 11, 20, 16, 50, 59), 255, 1), ('903', datetime.datetime(2019, 11, 20, 16, 51, 5), 255, 1), ('904', datetime.datetime(2019, 11, 20, 16, 51, 7), 255, 1), ('900', datetime.datetime(2019, 11, 20, 16, 51, 9), 255, 1), ('14', datetime.datetime(2019, 11, 20, 16, 51, 47), 255, 1), ('901', datetime.datetime(2019, 11, 20, 16, 51, 49), 255, 1), ('909', datetime.datetime(2019, 11, 20, 16, 52, 33), 255, 1)] 

Can someone suggest a way to do this ? I'd like to get this result :

14 = [datetime.datetime(2019, 11, 20, 16, 37),datetime.datetime(2019, 11, 20, 16, 50, 7),datetime.datetime(2019, 11, 20, 16, 51, 47), 255, 1)] 901 = [datetime.datetime(2019, 11, 20, 16, 39, 56),datetime.datetime(2019, 11, 20, 16, 49, 10),datetime.datetime(2019, 11, 20, 16, 50, 59),datetime.datetime(2019, 11, 20, 16, 51, 49)] 903 = [datetime.datetime(2019, 11, 20, 16, 51, 5), 255, 1)] 904 = [datetime.datetime(2019, 11, 20, 16, 51, 7)] 900 = [datetime.datetime(2019, 11, 20, 16, 51, 9)] 909 = [datetime.datetime(2019, 11, 20, 16, 52, 33)] 
3
  • 1
    You can't assign integers as variable names. BTW What have you tried so far? Commented Nov 20, 2019 at 20:00
  • You are going to want a dictionary because, as stated, you can't have just numerical values as names, nor would you want to create all the names in the global namespace Commented Nov 20, 2019 at 20:02
  • They already did. The expected output clearly shows multiple timestamps against the 14 key Commented Nov 20, 2019 at 20:29

5 Answers 5

1

This can be done with a dict comprehension using itertools.groupby and operator.itemgetter:

#sort the list first atten.sort() grouped = {k: [e[1] for e in g] for k, g in groupby(atten, itemgetter(0))} 

Results:

{'14': [datetime.datetime(2019, 11, 20, 16, 37), datetime.datetime(2019, 11, 20, 16, 50, 7), datetime.datetime(2019, 11, 20, 16, 51, 47)], '900': [datetime.datetime(2019, 11, 20, 16, 51, 9)], '901': [datetime.datetime(2019, 11, 20, 16, 39,56), datetime.datetime(2019, 11, 20, 16, 49, 10), datetime.datetime(2019, 11, 20, 16, 50, 59), datetime.datetime(2019, 11, 20, 16, 51, 49)], '903': [datetime.datetime(2019, 11, 20, 16, 51, 5)], '904': [datetime.datetime(2019, 11, 20, 16, 51, 7)], '909': [datetime.datetime(2019, 11, 20, 16, 52, 33)]} 
Sign up to request clarification or add additional context in comments.

1 Comment

No it can't. You've lost the duplicates against the 14 and 901 keys that are clearly visible in the input data and the expected output
1

All of the answers are just getting more and more elaborate. You just need (or, really, want) a defaultdict.

atten = [('14', datetime.datetime(2019, 11, 20, 16, 37), 255, 1), ('901', datetime.datetime(2019, 11, 20, 16, 39, 56), 255, 1), ('901', datetime.datetime(2019, 11, 20, 16, 49, 10), 255, 1), ('14', datetime.datetime(2019, 11, 20, 16, 50, 7), 255, 1), ('901', datetime.datetime(2019, 11, 20, 16, 50, 59), 255, 1), ('903', datetime.datetime(2019, 11, 20, 16, 51, 5), 255, 1), ('904', datetime.datetime(2019, 11, 20, 16, 51, 7), 255, 1), ('900', datetime.datetime(2019, 11, 20, 16, 51, 9), 255, 1), ('14', datetime.datetime(2019, 11, 20, 16, 51, 47), 255, 1), ('901', datetime.datetime(2019, 11, 20, 16, 51, 49), 255, 1), ('909', datetime.datetime(2019, 11, 20, 16, 52, 33), 255, 1)] aggregated = defaultdict(list) for row in atten: aggregated[row[0]].append(row[1]) 

That's it. There's no need for map, lambda, dict comprehensions or anything. They will be slower and are harder to mentally grok. 3 lines of code.

Comments

1

Just use a defaultdict with list as the standard parameter

import datetime atten = [('14', datetime.datetime(2019, 11, 20, 16, 37), 255, 1), ('901', datetime.datetime(2019, 11, 20, 16, 39, 56), 255, 1), ('901', datetime.datetime(2019, 11, 20, 16, 49, 10), 255, 1), ('14', datetime.datetime(2019, 11, 20, 16, 50, 7), 255, 1), ('901', datetime.datetime(2019, 11, 20, 16, 50, 59), 255, 1), ('903', datetime.datetime(2019, 11, 20, 16, 51, 5), 255, 1), ('904', datetime.datetime(2019, 11, 20, 16, 51, 7), 255, 1), ('900', datetime.datetime(2019, 11, 20, 16, 51, 9), 255, 1), ('14', datetime.datetime(2019, 11, 20, 16, 51, 47), 255, 1), ('901', datetime.datetime(2019, 11, 20, 16, 51, 49), 255, 1), ('909', datetime.datetime(2019, 11, 20, 16, 52, 33), 255, 1)] from collections import defaultdict result = defaultdict(list) for item in atten: result[item[0]].append(item[1]) print(result) 

Which yields

defaultdict(<type 'list'>, {'903': [datetime.datetime(2019, 11, 20, 16, 51, 5)], '900': [datetime.datetime(2019, 11, 20, 16, 51, 9)], '901': [datetime.datetime(2019, 11, 20, 16, 39, 56), datetime.datetime(2019, 11, 20, 16, 49, 10), datetime.datetime(2019, 11, 20, 16, 50, 59), datetime.datetime(2019, 11, 20, 16, 51, 49)], '14': [datetime.datetime(2019, 11, 20, 16, 37), datetime.datetime(2019, 11, 20, 16, 50, 7), datetime.datetime(2019, 11, 20, 16, 51, 47)], '904': [datetime.datetime(2019, 11, 20, 16, 51, 7)], '909': [datetime.datetime(2019, 11, 20, 16, 52, 33)]}) 

1 Comment

That's exploiting side effects. Why you would want _ = [result[item[0]].append(item[1]) for item in atten] to just eat up a non(e)-sensical list rather than just use a loop is beyond me. That's bad practice
0

You just need to use a dict to group the elements using the first tuple value as the key, and append the rest of the tuple to the value (setting the default to an empty list).

import datetime array = [('14', datetime.datetime(2019, 11, 20, 16, 37), 255, 1), ('901', datetime.datetime(2019, 11, 20, 16, 39, 56), 255, 1), ('901', datetime.datetime(2019, 11, 20, 16, 49, 10), 255, 1), ('14', datetime.datetime(2019, 11, 20, 16, 50, 7), 255, 1), ('901', datetime.datetime(2019, 11, 20, 16, 50, 59), 255, 1), ('903', datetime.datetime(2019, 11, 20, 16, 51, 5), 255, 1), ('904', datetime.datetime(2019, 11, 20, 16, 51, 7), 255, 1), ('900', datetime.datetime(2019, 11, 20, 16, 51, 9), 255, 1), ('14', datetime.datetime(2019, 11, 20, 16, 51, 47), 255, 1), ('901', datetime.datetime(2019, 11, 20, 16, 51, 49), 255, 1), ('909', datetime.datetime(2019, 11, 20, 16, 52, 33), 255, 1)] def group(array): res = {} for elem in array: key = elem[0] rest = elem[1:] res.setdefault(key, []).append(rest) return res grouped_array = group(array) print(grouped_array) 

Comments

0

To group dates based on the initial value of each tuple you would use a for and default value in a dictionary:

import datetime atten = [ ('14', datetime.datetime(2019, 11, 20, 16, 37), 255, 1), ('901', datetime.datetime(2019, 11, 20, 16, 39, 56), 255, 1), ('901', datetime.datetime(2019, 11, 20, 16, 49, 10), 255, 1), ('14', datetime.datetime(2019, 11, 20, 16, 50, 7), 255, 1), ('901', datetime.datetime(2019, 11, 20, 16, 50, 59), 255, 1), ('903', datetime.datetime(2019, 11, 20, 16, 51, 5), 255, 1), ('904', datetime.datetime(2019, 11, 20, 16, 51, 7), 255, 1), ('900', datetime.datetime(2019, 11, 20, 16, 51, 9), 255, 1), ('14', datetime.datetime(2019, 11, 20, 16, 51, 47), 255, 1), ('901', datetime.datetime(2019, 11, 20, 16, 51, 49), 255, 1), ('909', datetime.datetime(2019, 11, 20, 16, 52, 33), 255, 1) ] grouped_data = {} for data in atten: index = data[0] date = data[1] grouped_data[index] = grouped_data.get(index, []) + [date] print(grouped_data) #{ # '14': [ # datetime.datetime(2019, 11, 20, 16, 37), # datetime.datetime(2019, 11, 20, 16, 50, 7), # datetime.datetime(2019, 11, 20, 16, 51, 47) # ], # '901': [ # datetime.datetime(2019, 11, 20, 16, 39, 56), # datetime.datetime(2019, 11, 20, 16, 49, 10), # datetime.datetime(2019, 11, 20, 16, 50, 59), # datetime.datetime(2019, 11, 20, 16, 51, 49) # ], # '903': [datetime.datetime(2019, 11, 20, 16, 51, 5)], # '904': [datetime.datetime(2019, 11, 20, 16, 51, 7)], # '900': [datetime.datetime(2019, 11, 20, 16, 51, 9)], # '909': [datetime.datetime(2019, 11, 20, 16, 52, 33)] #} 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.