简体   繁体   中英

Python convert list of tuples to json

I have list of tuples like :

[('a', '76', '20190208011713-0500'),
 ('b', '14', '20190208011713-0500'),
 ('c', '99', '20190208011713-0500'),
 ('d', '62', '20190208011713-0500'),
 ('e', '112', '20190208011713-0500'),
 ('f', '78', '20190208011713-0500'),
 ('g', '20', '20190208011713-0500'),
 ('h', '14', '20190208011713-0500'),
 ('i', '23', '20190208011713-0500'),
 ('a', '45', '20190208011803-0500'),
 ('b', '36', '20190208011803-0500'),
 ('c', '22', '20190208011803-0500'),
 ('d', '69', '20190208011803-0500'),
 ('e', '11', '20190208011803-0500'),
 ('f', '118', '20190208011803-0500'),
 ('g', '29', '20190208011803-0500'),
 ('h', '34', '20190208011803-0500'),
 ('i', '63', '20190208011803-0500')]

The third element of all the tuples are the same. I am trying to convert this list into a dictionary in the following way:

{timestamp: 20190208011713-0500,
  'a' : 76,
  'b' : 14,
  'c' : 99,
  'd' : 62,
  'e' : 112,
  'f' : 78,
  'g' : 20,
  'h' : 14,
  'i' : 23}

UPDATE:

As of now I am doing it manually but I have around 1000's of tuples in a list with the same timestamp, but sometimes I do also have different timestamps. I am trying to automate this process by writing a function as I need to re-use the code again and again for multiple list of tuples to create list of dictionaries but I'm not sure how to approach this problem. Any help would be appreciated?

[{'timestamp': '20190208011713-0500',
  'a' : 76,
  'b' : 14,
  'c' : 99,
  'd' : 62,
  'e' : 112,
  'f' : 78,
  'g' : 20,
  'h' : 14,
  'i' : 23}, 
  {'timestamp': '20190208011803-0500',
  'a' : 45,
  'b' : 36,
  'c' : 22,
  'd' : 69,
  'e' : 11,
  'f' : 118,
  'g' : 29,
  'h' : 34,
  'i' : 63}]

If the timestamp is guaranteed to be the same, or otherwise you don't care if it isn't, then just use:

result = {'timestamp': your_list[0][-1]}
result.update(tup[:2] for tup in your_list)

The second line takes the first two elements of each tuple, and passes those directly to the dict.update() method . Like the dict() constructor , that method accepts an iterable of (key, value) tuples, and with slicing, that's what you have already.

Demo:

>>> result = {'timestamp': your_list[0][-1]}
>>> result.update(tup[:2] for tup in your_list)
>>> from pprint import pprint
>>> pprint(result)
{'a': '76',
 'b': '14',
 'c': '99',
 'd': '62',
 'e': '112',
 'f': '78',
 'g': '20',
 'h': '14',
 'i': '23',
 'timestamp': '20190208011713-0500'}

If speed is of the essence, you can use operator.itemgetter() to do the fetching, and use the Python 3 version of map() to apply it when updating:

from operator import itemgetter
try:
    # forward compatibility with Python 3
    from future_builtins import map
except ImportError:
    pass

result = {'timestamp': your_list[0][-1]}
result.update(map(itemgetter(0, 1), your_list))

With those changes the whole result.update() loop is executed in native C code.

If your timestamps are not guaranteed to be the same and you need to produce a list, you need to split out (group) your tuples by timestamp. If your input is at least grouped (all entries with the same timestamp appear consecutively), then you can use itertools.groupby() to do the grouping. The way you then build each dictionary remains the same; we can use the itemgetter() calleble here too to produce the grouping key:

from itertools import groupby
from operator import itemgetter
try:
    # forward compatibility with Python 3
    from future_builtins import map
except ImportError:
    pass

def group_timestamp(timestamp, group):
    d = {'timestamp': timestamp}
    d.update(map(itemgetter(0, 1), group))
    return d

result = [group_timestamp(ts, group) for ts, group in groupby(your_list, itemgetter(2))]

If they are not grouped, then I'd not sort the input. You want to shunt them into each timestamp group linearly, using a dictionary to do the grouping, then just sort the values of that dictionary when producing the output:

groups = {}
for key, value, ts in your_list:
    if ts not in groups:
        groups[ts] = {'timestamp': ts}
    groups[ts][key] = value

result = sorted(groups.values(), key=itemgetter('timestamp'))

This gives you the grouped dicitonaries in timestamp order. If output order doesn't matter, just use result = list(groups.values()) .

Accounting for changing timestamps:

lst = [('a', '76', '20190208011713-0500'),
    ('b', '14', '20190208011713-0500'),
    ('c', '99', '20190208011713-0500'),
    ('d', '62', '20190208011713-0500'),
    ('e', '112', '20190208011713-0500'),
    ('f', '78', '20190208011713-0500'),
    ('g', '20', '20190208011713-0500'),
    ('h', '14', '20190208011713-0500'),
    ('i', '23', '20190208011713-0500')]

dict = {}

for tuple in lst:
    if tuple[2] in dict:
        dict[tuple[2]][tuple[0]] = tuple[1]
    else:
        dict[tuple[2]] = {}
        dict[tuple[2]][tuple[0]] = tuple[1]

OUTPUT:

{'20190208011713-0500': {'a': '76',
  'b': '14',
  'c': '99',
  'd': '62',
  'e': '112',
  'f': '78',
  'g': '20',
  'h': '14',
  'i': '23'}}
tups = [('a', '76', '20190208011713-0500'),
 ('b', '14', '20190208011713-0500'),
 ('c', '99', '20190208011713-0500'),
 ('d', '62', '20190208011713-0500'),
 ('e', '112', '20190208011713-0500'),
 ('f', '78', '20190208011713-0500'),
 ('g', '20', '20190208011713-0500'),
 ('h', '14', '20190208011713-0500'),
 ('i', '23', '20190208011713-0500')]


def to_dict(tups):
    my_dict = {element[0]: element[1] for element in tups}
    my_dict['timestamp'] = tups[-1][2] 
    return my_dict

m_d = to_dict(tups)
print(m_d) 

I think the simplest way is the following:

return_dict = dict([item[:2] for item in your_list])
return_dict["timestamp"] = your_list[0][2]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM