Related
I have a '.txt' file that contains JSON data like below.
[{'tradable': True, 'mode': 'full', 'instrument_token': 4708097, 'last_price': 178.65, 'last_traded_quantity': 5, 'average_traded_price': 180.1, 'volume_traded': 4581928, 'total_buy_quantity': 1282853, 'total_sell_quantity': 1673842, 'ohlc': {'open': 181.95, 'high': 181.95, 'low': 177.8, 'close': 181.0}, 'change': -1.2983425414364609, 'last_trade_time': datetime.datetime(2023, 1, 12, 13, 4, 58), 'oi': 0, 'oi_day_high': 0, 'oi_day_low': 0, 'exchange_timestamp': datetime.datetime(2023, 1, 12, 13, 5, 1), 'depth': {'buy': [{'quantity': 653, 'price': 178.6, 'orders': 8}, {'quantity': 2408, 'price': 178.55, 'orders': 15}, {'quantity': 6329, 'price': 178.5, 'orders': 22}, {'quantity': 9161, 'price': 178.45, 'orders': 24}, {'quantity': 7775, 'price': 178.4, 'orders': 17}], 'sell': [{'quantity': 5726, 'price': 178.7, 'orders': 8}, {'quantity': 4099, 'price': 178.75, 'orders': 11}, {'quantity': 23951, 'price': 178.8, 'orders': 25}, {'quantity': 7446, 'price': 178.85, 'orders': 21}, {'quantity': 11379, 'price': 178.9, 'orders': 21}]}}, {'tradable': True, 'mode': 'full', 'instrument_token': 871681, 'last_price': 972.55, 'last_traded_quantity': 1, 'average_traded_price': 973.85, 'volume_traded': 411290, 'total_buy_quantity': 152925, 'total_sell_quantity': 214765, 'ohlc': {'open': 971.75, 'high': 978.6, 'low': 969.0, 'close': 967.75}, 'change': 0.4959958667011061, 'last_trade_time': datetime.datetime(2023, 1, 12, 13, 4, 53), 'oi': 0, 'oi_day_high': 0, 'oi_day_low': 0, 'exchange_timestamp': datetime.datetime(2023, 1, 12, 13, 5, 4), 'depth': {'buy': [{'quantity': 6, 'price': 972.15, 'orders': 2}, {'quantity': 3, 'price': 972.1, 'orders': 2}, {'quantity': 15, 'price': 972.05, 'orders': 3}, {'quantity': 455, 'price': 972.0, 'orders': 16}, {'quantity': 14, 'price': 971.95, 'orders': 2}], 'sell': [{'quantity': 6, 'price': 972.5, 'orders': 3}, {'quantity': 49, 'price': 972.55, 'orders': 2}, {'quantity': 10, 'price': 972.6, 'orders': 1}, {'quantity': 27, 'price': 972.65, 'orders': 2}, {'quantity': 10, 'price': 972.7, 'orders': 1}]}}]
This data was written to a .txt file after it was recieved from zerodha websocket. Now, I want to read the data from the .txt file using my python script and want to load it as a json. But the json.loads() method in python throws the below error.
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 3 (char 2)
I have tried eval and ast.literal_eval methods in python as well but it didn't solve my problem. All I want is to be able to read the above data as a JSON to my python script. Any leads would be of great help.
Let me start off with THIS IS A BAD IDEA.
The comments on the question call out that this is not a JSON object in a file, rather the result of some other Python process printing the result and putting that in a file. The correct solution would be to modify the producer to use json.dumps() instead.
That aside, here's a DANGEROUS way to read that source file into a Python object.
import datetime # needed for `eval()`
with open('textfile.txt', 'r') as f:
data = eval(f.read())
from pprint import pprint
pprint(data)
This will produce the following output from that input:
[{'average_traded_price': 180.1,
'change': -1.2983425414364609,
'depth': {'buy': [{'orders': 8, 'price': 178.6, 'quantity': 653},
{'orders': 15, 'price': 178.55, 'quantity': 2408},
{'orders': 22, 'price': 178.5, 'quantity': 6329},
{'orders': 24, 'price': 178.45, 'quantity': 9161},
{'orders': 17, 'price': 178.4, 'quantity': 7775}],
'sell': [{'orders': 8, 'price': 178.7, 'quantity': 5726},
{'orders': 11, 'price': 178.75, 'quantity': 4099},
{'orders': 25, 'price': 178.8, 'quantity': 23951},
{'orders': 21, 'price': 178.85, 'quantity': 7446},
{'orders': 21, 'price': 178.9, 'quantity': 11379}]},
'exchange_timestamp': datetime.datetime(2023, 1, 12, 13, 5, 1),
'instrument_token': 4708097,
'last_price': 178.65,
'last_trade_time': datetime.datetime(2023, 1, 12, 13, 4, 58),
'last_traded_quantity': 5,
'mode': 'full',
'ohlc': {'close': 181.0, 'high': 181.95, 'low': 177.8, 'open': 181.95},
'oi': 0,
'oi_day_high': 0,
'oi_day_low': 0,
'total_buy_quantity': 1282853,
'total_sell_quantity': 1673842,
'tradable': True,
'volume_traded': 4581928},
{'average_traded_price': 973.85,
'change': 0.4959958667011061,
'depth': {'buy': [{'orders': 2, 'price': 972.15, 'quantity': 6},
{'orders': 2, 'price': 972.1, 'quantity': 3},
{'orders': 3, 'price': 972.05, 'quantity': 15},
{'orders': 16, 'price': 972.0, 'quantity': 455},
{'orders': 2, 'price': 971.95, 'quantity': 14}],
'sell': [{'orders': 3, 'price': 972.5, 'quantity': 6},
{'orders': 2, 'price': 972.55, 'quantity': 49},
{'orders': 1, 'price': 972.6, 'quantity': 10},
{'orders': 2, 'price': 972.65, 'quantity': 27},
{'orders': 1, 'price': 972.7, 'quantity': 10}]},
'exchange_timestamp': datetime.datetime(2023, 1, 12, 13, 5, 4),
'instrument_token': 871681,
'last_price': 972.55,
'last_trade_time': datetime.datetime(2023, 1, 12, 13, 4, 53),
'last_traded_quantity': 1,
'mode': 'full',
'ohlc': {'close': 967.75, 'high': 978.6, 'low': 969.0, 'open': 971.75},
'oi': 0,
'oi_day_high': 0,
'oi_day_low': 0,
'total_buy_quantity': 152925,
'total_sell_quantity': 214765,
'tradable': True,
'volume_traded': 411290}]
Again, I will restate, THIS IS A BAD IDEA.
Read more on the specifics of eval here: https://realpython.com/python-eval-function/
Your JSON is not valid. You can check that by using an online JSON validator like this one: https://jsonformatter.org/
After entering the “JSON”, you can see it is not in a valid format.
You could either export it right, which I would highly recommend, or you could replace the wrong chars.
Currently, you have three issues:
You are using single quotes instead of double quotes
You are not parsing your datetime object, it looks like you just insert the object, you have to serialize it
You are writing true values as True, but that is the python way and not the JSON way. You either have to write it as true, or you have to pass it as a string. I would recommend the first one.
It could look like this (but I didnt parse datetime right, I just stringified it):
[{"tradable": true, "mode": "full", "instrument_token": 4708097, "last_price": 178.65, "last_traded_quantity": 5, "average_traded_price": 180.1, "volume_traded": 4581928, "total_buy_quantity": 1282853, "total_sell_quantity": 1673842, "ohlc": {"open": 181.95, "high": 181.95, "low": 177.8, "close": 181.0}, "change": -1.2983425414364609, "last_trade_time": "datetime.datetime(2023, 1, 12, 13, 4, 58)", "oi": 0, "oi_day_high": 0, "oi_day_low": 0, "exchange_timestamp": "datetime.datetime(2023, 1, 12, 13, 5, 1)", "depth": {"buy": [{"quantity": 653, "price": 178.6, "orders": 8}, {"quantity": 2408, "price": 178.55, "orders": 15}, {"quantity": 6329, "price": 178.5, "orders": 22}, {"quantity": 9161, "price": 178.45, "orders": 24}, {"quantity": 7775, "price": 178.4, "orders": 17}], "sell": [{"quantity": 5726, "price": 178.7, "orders": 8}, {"quantity": 4099, "price": 178.75, "orders": 11}, {"quantity": 23951, "price": 178.8, "orders": 25}, {"quantity": 7446, "price": 178.85, "orders": 21}, {"quantity": 11379, "price": 178.9, "orders": 21}]}}, {"tradable": true, "mode": "full", "instrument_token": 871681, "last_price": 972.55, "last_traded_quantity": 1, "average_traded_price": 973.85, "volume_traded": 411290, "total_buy_quantity": 152925, "total_sell_quantity": 214765, "ohlc": {"open": 971.75, "high": 978.6, "low": 969.0, "close": 967.75}, "change": 0.4959958667011061, "last_trade_time": "datetime.datetime(2023, 1, 12, 13, 4, 53)", "oi": 0, "oi_day_high": 0, "oi_day_low": 0, "exchange_timestamp": "datetime.datetime(2023, 1, 12, 13, 5, 4)", "depth": {"buy": [{"quantity": 6, "price": 972.15, "orders": 2}, {"quantity": 3, "price": 972.1, "orders": 2}, {"quantity": 15, "price": 972.05, "orders": 3}, {"quantity": 455, "price": 972.0, "orders": 16}, {"quantity": 14, "price": 971.95, "orders": 2}], "sell": [{"quantity": 6, "price": 972.5, "orders": 3}, {"quantity": 49, "price": 972.55, "orders": 2}, {"quantity": 10, "price": 972.6, "orders": 1}, {"quantity": 27, "price": 972.65, "orders": 2}, {"quantity": 10, "price": 972.7, "orders": 1}]}}]
I have a list with barline ticks and midi notes that can overlap the barlines. So I made a list of 'barlineticks':
barlinepos = [0, 768.0, 1536.0, 2304.0, 3072.0, 3840.0, 4608.0, 5376.0, 6144.0, 6912.0, 0, 576.0, 1152.0, 1728.0, 2304.0, 2880.0, 3456.0, 4032.0, 4608.0, 5184.0, 5760.0, 6336.0, 6912.0, 7488.0]
And a MidiFile:
{'type': 'time_signature', 'numerator': 4, 'denominator': 4, 'time': 0, 'duration': 768, 'ID': 0}
{'type': 'set_tempo', 'tempo': 500000, 'time': 0, 'ID': 1}
{'type': 'track_name', 'name': 'Tempo Track', 'time': 0, 'ID': 2}
{'type': 'track_name', 'name': 'New Instrument', 'time': 0, 'ID': 3}
{'type': 'note_on', 'time': 0, 'channel': 0, 'note': 48, 'velocity': 100, 'ID': 4, 'duration': 956}
{'type': 'time_signature', 'numerator': 3, 'denominator': 4, 'time': 768, 'duration': 6911, 'ID': 5}
{'type': 'note_on', 'time': 768, 'channel': 0, 'note': 46, 'velocity': 100, 'ID': 6, 'duration': 575}
{'type': 'note_off', 'time': 956, 'channel': 0, 'note': 48, 'velocity': 0, 'ID': 7}
{'type': 'note_off', 'time': 1343, 'channel': 0, 'note': 46, 'velocity': 0, 'ID': 8}
{'type': 'end_of_track', 'time': 7679, 'ID': 9}
And I want to check if the midi note is overlapping a barline. Every note_on message has a 'time' and a 'duration' value. I have to check if one of the barlineticks(in the list) is inside the range of the note('time' and 'duration'). I tried:
if barlinepos in range(0, 956):
print(True)
Of course this doesn't work because barlinepos is a list. How can I check if one of the values in the list results in True?
Simple iteration to solve the requirement:
for i in midifile:
start, end = i["time"], i["time"]+i["duration"]
for j in barlinepos:
if j >= start and j<= end:
print(True)
break
print(False)
This question already has answers here:
How to remove items from a list while iterating?
(25 answers)
Closed 2 years ago.
I'm trying to add a unique ID to every item in a list and struggling with some strange behaviour I don't understand from Python.
I have this function:
def add_IDs(d):
for x in range(len(d)):
var = d.pop(x)
var['list_id'] = x
d.insert(x, var)
return d
Into which I input this data:
[{'db_number': 1, 'quantity': 15, 'quality': 1},
{'db_number': 1, 'quantity': 20, 'quality': 0},
{'db_number': 1, 'quantity': 20, 'quality': 0},
{'db_number': 1, 'quantity': 80, 'quality': 0},
{'db_number': 2, 'quantity': 4, 'quality': 0}]
I expect this output:
[{'db_number': 1, 'quantity': 15, 'quality': 1, 'list_id': 0},
{'db_number': 1, 'quantity': 20, 'quality': 0, 'list_id': 1},
{'db_number': 1, 'quantity': 20, 'quality': 0, 'list_id': 2},
{'db_number': 1, 'quantity': 80, 'quality': 0, 'list_id': 3},
{'db_number': 2, 'quantity': 4, 'quality': 0, 'list_id': 4}]
But instead the second dict in the list, gets 'list_id': 2 instead of 'list_id': 1
[{'db_number': 1, 'quantity': 15, 'quality': 1, 'list_id': 0},
{'db_number': 1, 'quantity': 20, 'quality': 0, 'list_id': 2},
{'db_number': 1, 'quantity': 20, 'quality': 0, 'list_id': 2},
{'db_number': 1, 'quantity': 80, 'quality': 0, 'list_id': 3},
{'db_number': 2, 'quantity': 4, 'quality': 0, 'list_id': 4}]
As a test I wrote this:
def add_IDs(d):
for x in range(len(d)):
var = d.pop(x)
var['list_id'] = x
d.insert(x, var)
return d
data2 = [{'db_number': 1, 'quantity': 15, 'quality': 1},
{'db_number': 1, 'quantity': 20, 'quality': 0},
{'db_number': 1, 'quantity': 20, 'quality': 0},
{'db_number': 1, 'quantity': 80, 'quality': 0},
{'db_number': 2, 'quantity': 4, 'quality': 0}]
print(data)
print(data2)
l1 = add_IDs(data)
l2 = add_IDs(data2)
print(l1)
print(l2)
print("")
print('Does data = data2?')
print(data == data2)
print('Does l1 = l2?')
print(l1 == l2)
Which gives this output:
[{'db_number': 1, 'quantity': 15, 'quality': 1}, {'db_number': 1, 'quantity': 20, 'quality': 0}, {'db_number': 1, 'quantity': 20, 'quality': 0}, {'db_number': 1, 'quantity': 80, 'quality': 0}, {'db_number': 2, 'quantity': 4, 'quality': 0}]
[{'db_number': 1, 'quantity': 15, 'quality': 1}, {'db_number': 1, 'quantity': 20, 'quality': 0}, {'db_number': 1, 'quantity': 20, 'quality': 0}, {'db_number': 1, 'quantity': 80, 'quality': 0}, {'db_number': 2, 'quantity': 4, 'quality': 0}]
[{'db_number': 1, 'quantity': 15, 'quality': 1, 'list_id': 0}, {'db_number': 1, 'quantity': 20, 'quality': 0, 'list_id': 2}, {'db_number': 1, 'quantity': 20, 'quality': 0, 'list_id': 2}, {'db_number': 1, 'quantity': 80, 'quality': 0, 'list_id': 3}, {'db_number': 2, 'quantity': 4, 'quality': 0, 'list_id': 4}]
[{'db_number': 1, 'quantity': 15, 'quality': 1, 'list_id': 0}, {'db_number': 1, 'quantity': 20, 'quality': 0, 'list_id': 1}, {'db_number': 1, 'quantity': 20, 'quality': 0, 'list_id': 2}, {'db_number': 1, 'quantity': 80, 'quality': 0, 'list_id': 3}, {'db_number': 2, 'quantity': 4, 'quality': 0, 'list_id': 4}]
Does data = data2?
False
Does l1 = l2?
False
Process finished with exit code 0
As far as I can see, the input data is identical for both, the inbuilt comparison tool tells me the printed values are identical, but the output is still different and the checks say they are different. Can someone shed some light on what I'm missing?
First off, you can simplify your logic substantially:
def add_ids(items):
for index, item in enumerate(items):
item['list_id'] = index
I was unable to reproduce your issue in python 2 or python3.
Note that the len issue mentioned in a comment will not come into play, since you calculate it once, when the range is created, not at each point in the list.
With the additional information from your comment that the approach above gave the same behavior, I know your issue - you are using the same object for two entries in your list.
x, y, z = {}, {}, {}
items = [x, y, y, z]
for index, item in enumerate(items):
print(index, item, id(item))
Note that index 1 and 2 have the same id
0 {} 4446764960
1 {} 4446764960
2 {} 4446790512
3 {} 4430894656
Then running
add_ids(items)
sets the index for y twice, once for index 1 and then for index 2.
assert items == [{'list_id': 0}, {'list_id': 2}, {'list_id': 2}, {'list_id': 3}]
Any change to y will show up in both items[1] and items[2], since they are the same object.
I have a dataframe that has JSON values are in columns. Those were indented into multiple levels. I would like to extract the end key and value into a new dataframe. I will give you sample column values below
{'shipping_assignments': [{'shipping': {'address': {'address_type':
'shipping', 'city': 'Calder', 'country_id': 'US',
'customer_address_id': 1, 'email': 'roni_cost#example.com',
'entity_id': 1, 'firstname': 'Veronica', 'lastname': 'Costello',
'parent_id': 1, 'postcode': '49628-7978', 'region': 'Michigan',
'region_code': 'MI', 'region_id': 33, 'street': ['6146 Honey Bluff
Parkway'], 'telephone': '(555) 229-3326'}, 'method':
'flatrate_flatrate', 'total': {'base_shipping_amount': 5,
'base_shipping_discount_amount': 0,
'base_shipping_discount_tax_compensation_amnt': 0,
'base_shipping_incl_tax': 5, 'base_shipping_invoiced': 5,
'base_shipping_tax_amount': 0, 'shipping_amount': 5,
'shipping_discount_amount': 0,
'shipping_discount_tax_compensation_amount': 0, 'shipping_incl_tax':
5, 'shipping_invoiced': 5, 'shipping_tax_amount': 0}}, 'items':
[{'amount_refunded': 0, 'applied_rule_ids': '1',
'base_amount_refunded': 0, 'base_discount_amount': 0,
'base_discount_invoiced': 0, 'base_discount_tax_compensation_amount':
0, 'base_discount_tax_compensation_invoiced': 0,
'base_original_price': 29, 'base_price': 29, 'base_price_incl_tax':
31.39, 'base_row_invoiced': 29, 'base_row_total': 29, 'base_row_total_incl_tax': 31.39, 'base_tax_amount': 2.39,
'base_tax_invoiced': 2.39, 'created_at': '2019-09-27 10:03:45',
'discount_amount': 0, 'discount_invoiced': 0, 'discount_percent': 0,
'free_shipping': 0, 'discount_tax_compensation_amount': 0,
'discount_tax_compensation_invoiced': 0, 'is_qty_decimal': 0,
'item_id': 1, 'name': 'Iris Workout Top', 'no_discount': 0,
'order_id': 1, 'original_price': 29, 'price': 29, 'price_incl_tax':
31.39, 'product_id': 1434, 'product_type': 'configurable', 'qty_canceled': 0, 'qty_invoiced': 1, 'qty_ordered': 1,
'qty_refunded': 0, 'qty_shipped': 1, 'row_invoiced': 29, 'row_total':
29, 'row_total_incl_tax': 31.39, 'row_weight': 1, 'sku':
'WS03-XS-Red', 'store_id': 1, 'tax_amount': 2.39, 'tax_invoiced':
2.39, 'tax_percent': 8.25, 'updated_at': '2019-09-27 10:03:46', 'weight': 1, 'product_option': {'extension_attributes':
{'configurable_item_options': [{'option_id': '141', 'option_value':
167}, {'option_id': '93', 'option_value': 58}]}}}]}],
'payment_additional_info': [{'key': 'method_title', 'value': 'Check /
Money order'}], 'applied_taxes': [{'code': 'US-MI--Rate 1', 'title':
'US-MI--Rate 1', 'percent': 8.25, 'amount': 2.39, 'base_amount':
2.39}], 'item_applied_taxes': [{'type': 'product', 'applied_taxes': [{'code': 'US-MI--Rate 1', 'title': 'US-MI--Rate 1', 'percent':
8.25, 'amount': 2.39, 'base_amount': 2.39}]}], 'converting_from_quote': True}
Above is single row value of the dataframe column df['x']
My codes are below to convert
sample = data['x'].tolist()
data = json.dumps(sample)
df = pd.read_json(data)
it gives new dataframe with columns
Index(['applied_taxes', 'converting_from_quote', 'item_applied_taxes',
'payment_additional_info', 'shipping_assignments'],
dtype='object')
When I tried to do the same above to convert the column which has row values
m_df = df['applied_taxes'].apply(lambda x : re.sub('.?\[|$.|]',"", str(x)))
m_sample = m_df.tolist()
m_data = json.dumps(m_sample)
c_df = pd.read_json(m_data)
It doesn't work
Check this link to get the beautified_json
I came across a beautiful ETL package in python called petl. convert the json list into dict form with the help of function called fromdicts(json_string)
order_table = fromdicts(data_list)
If you find any nested dict in any of the columns, use unpackdict(order_table,'nested_col')
it will unpack the nested dict.
In my case, I need to unpack the applied_tax column. Below code will unpack and append the key and value as a column and row in the same table.
order_table = unpackdict(order_table, 'applied_taxes')
If you guys wants to know more about -petl
It seems that your mistake was in tolist(). Try the following:
import pandas as pd
import json
import re
data = {"shipping_assignments":[{"shipping":{"address":{"address_type":"shipping","city":"Calder","country_id":"US","customer_address_id":1,"email":"roni_cost#example.com","entity_id":1,"firstname":"Veronica","lastname":"Costello","parent_id":1,"postcode":"49628-7978","region":"Michigan","region_code":"MI","region_id":33,"street":["6146 Honey Bluff Parkway"],"telephone":"(555) 229-3326"},"method":"flatrate_flatrate","total":{"base_shipping_amount":5,"base_shipping_discount_amount":0,"base_shipping_discount_tax_compensation_amnt":0,"base_shipping_incl_tax":5,"base_shipping_invoiced":5,"base_shipping_tax_amount":0,"shipping_amount":5,"shipping_discount_amount":0,"shipping_discount_tax_compensation_amount":0,"shipping_incl_tax":5,"shipping_invoiced":5,"shipping_tax_amount":0}},"items":[{"amount_refunded":0,"applied_rule_ids":"1","base_amount_refunded":0,"base_discount_amount":0,"base_discount_invoiced":0,"base_discount_tax_compensation_amount":0,"base_discount_tax_compensation_invoiced":0,"base_original_price":29,"base_price":29,"base_price_incl_tax":31.39,"base_row_invoiced":29,"base_row_total":29,"base_row_total_incl_tax":31.39,"base_tax_amount":2.39,"base_tax_invoiced":2.39,"created_at":"2019-09-27 10:03:45","discount_amount":0,"discount_invoiced":0,"discount_percent":0,"free_shipping":0,"discount_tax_compensation_amount":0,"discount_tax_compensation_invoiced":0,"is_qty_decimal":0,"item_id":1,"name":"Iris Workout Top","no_discount":0,"order_id":1,"original_price":29,"price":29,"price_incl_tax":31.39,"product_id":1434,"product_type":"configurable","qty_canceled":0,"qty_invoiced":1,"qty_ordered":1,"qty_refunded":0,"qty_shipped":1,"row_invoiced":29,"row_total":29,"row_total_incl_tax":31.39,"row_weight":1,"sku":"WS03-XS-Red","store_id":1,"tax_amount":2.39,"tax_invoiced":2.39,"tax_percent":8.25,"updated_at":"2019-09-27 10:03:46","weight":1,"product_option":{"extension_attributes":{"configurable_item_options":[{"option_id":"141","option_value":167},{"option_id":"93","option_value":58}]}}}]}],"payment_additional_info":[{"key":"method_title","value":"Check / Money order"}],"applied_taxes":[{"code":"US-MI-*-Rate 1","title":"US-MI-*-Rate 1","percent":8.25,"amount":2.39,"base_amount":2.39}],"item_applied_taxes":[{"type":"product","applied_taxes":[{"code":"US-MI-*-Rate 1","title":"US-MI-*-Rate 1","percent":8.25,"amount":2.39,"base_amount":2.39}]}],"converting_from_quote":"True"}
df = pd.read_json(json.dumps(data))
m_df = df['applied_taxes'].apply(lambda x : re.sub('.?\[|$.|]',"", str(x)))
c_df = pd.read_json(json.dumps(list(m_df)))
print(c_df)
prints the following:
0
0 {'code': 'US-MI-*-Rate 1', 'title': 'US-MI-*-R...
input={11: {'perc': 0, 'name': u'B test', 'cid': 11, 'total': 0, 'pending': 0, 'complete': 0}, 10: {'perc': 0, 'name': u'C test', 'cid': 10, 'total': 0, 'pending': 0,'complete': 0}, 3: {'perc': 9, 'name': u'Atest Pre-requisites', 'cid': 3, 'total': 11, 'pending': 10, 'complete': 1}}
I want to sort this dict based on name field. I'm new in python, anyone please help me.
First, you should avoid using reserved words (such as input) as variables (now input is redefined and no longer calls the function input()).
Also, a dictionary cannot be sorted. If you don't need the keys, you can transform the dictionary into a list, and then sort it. The code would be like this:
input_dict = {11: {'perc': 0, 'name': u'B test', 'cid': 11, 'total': 0, 'pending': 0, 'complete': 0}, 10: {'perc': 0, 'name': u'C test', 'cid': 10, 'total': 0, 'pending': 0,'complete': 0}, 3: {'perc': 9, 'name': u'Atest Pre-requisites', 'cid': 3, 'total': 11, 'pending': 10, 'complete': 1}}
input_list = sorted(input_dict.values(), key=lambda x: x['name'])
print(input_list)
# prints [{'perc': 9, 'complete': 1, 'cid': 3, 'total': 11, 'pending': 10, 'name': u'Atest Pre-requisites'}, {'perc': 0, 'complete': 0, 'cid': 11, 'total': 0, 'pending': 0, 'name': u'B test'}, {'perc': 0, 'complete': 0, 'cid': 10, 'total': 0, 'pending': 0, 'name': u'C test'}]
EDIT
If you wish to keep the keys and use iteritems() as you said in the comments, use this code instead:
input_dict = {11: {'perc': 0, 'name': u'B test', 'cid': 11, 'total': 0, 'pending': 0, 'complete': 0}, 10: {'perc': 0, 'name': u'C test', 'cid': 10, 'total': 0, 'pending': 0,'complete': 0}, 3: {'perc': 9, 'name': u'Atest Pre-requisites', 'cid': 3, 'total': 11, 'pending': 10, 'complete': 1}}
input_list = sorted(input_dict.iteritems(), key=lambda x: x[1]['name'])
print(input_list)
# prints [(3, {'perc': 9, 'complete': 1, 'cid': 3, 'total': 11, 'pending': 10, 'name': u'Atest Pre-requisites'}), (11, {'perc': 0, 'complete': 0, 'cid': 11, 'total': 0, 'pending': 0, 'name': u'B test'}), (10, {'perc': 0, 'complete': 0, 'cid': 10, 'total': 0, 'pending': 0, 'name': u'C test'})]