遍历字典键,传递到新字典,如果键不存在,则传递值为None的键

时间:2019-06-25 21:42:01

标签: python python-3.x loops dictionary iterator

编辑:这是我根据给定的答案想出想要的结果的结果。我将其包装在一个函数中。确保它不是最有效的,但可以起作用:)

for k in required_fields:
if k in response_data.keys():
    print(k, response_data[k])
else:
    print(k, None)

我是编程的新手(几个星期),这是我的第一个项目。

我正在从ByBit交换websocket收集时间序列数据,将JSON转换为Dict并将其存储到数据库中。网络套接字仅发送更新的数据,因此可以缺少一个或多个转换后的Dict键。我不弄清楚如何解决而不抛出KeyError。我尝试使用.get(),但它仅支持一个参数,而且我不确定如何在可迭代的条件下使用它来创建新字典。

最终,我想将所需的键值提交到postgres中,如果不存在或根本不传递值,则将Value传递为“ None”,并将表列留空。我不是我的经验不足,我不确定哪个更合适。

这是我转换为Dict后的消息示例,嵌套字典“数据”是可以变化的。例如,如果交易之间价格没有变化,价格将不会显示在消息中。

response_dict = ({'success': 'True', 'topic': 'trade.EOSUSD', 'data': [{'timestamp': '2019-06-20T10:06:36.030Z', 'symbol': 'EOSUSD', 'side': 'Sell',
                                                                    'size': 757, 'price': 6.77, 'tick_direction': 'PlusTick', 'trade_id': '5658ec5f-90ce-4244-9192-3f29057e223a', 'cross_seq': 59462597}]})

编辑:为澄清起见,这是来自同一订阅的另一种可能的消息的示例,例如价格没有变化,因此服务器没有发送价格键,值对。

response_dict = ({'success': 'True', 'topic': 'trade.EOSUSD', 'data': [{'timestamp': '2019-06-20T10:06:36.030Z', 'symbol': 'EOSUSD', 'side': 'Sell',
                                                                    'size': 757, 'tick_direction': 'PlusTick', 'trade_id': '5658ec5f-90ce-4244-9192-3f29057e223a', 'cross_seq': 59462597}]})

这是我用来提取嵌套字典'data'的函数,required_fields是我想提交给数据库的键。

def response_process(response_input):
    if "topic" in response_input and "trade" in response_input["topic"]:
        response_data = response_input["data"][0]
        required_fields = ['timestamp', 'symbol',
                           'side', 'size', 'price', 'tick_direction']
        response_data_2 = {key: value for key, value in response_data.items(
        ) if key in required_fields}
        updated_timestamp = str(datetime.datetime.strptime(
            response_data_2['timestamp'], '%Y-%m-%dT%H:%M:%S.%f%z'))
        response_data_2['timestamp'] = updated_timestamp
        commit_postgres(response_data_2)

这是我将这些数据提交到PostGres的方式

def commit_postgres(response_data_input):
    conn = psycopg2.connect(
        "dbname='postgres' user='postgres' password = 'postgres123' host='localhost' port= '5432'")
    cur = conn.cursor()
    cur.execute(
        "CREATE TABLE IF NOT EXISTS {symbol} (timestamp text, side text, size float, price float, tick_direction text)".format(**response_data_input))
    conn.commit()
    cur.execute("INSERT INTO {symbol}(timestamp, side, size, price, tick_direction) VALUES (%(timestamp)s, %(side)s, %(size)s, %(price)s, %(tick_direction)s)".format(
        **response_data_input), (response_data_input))
    conn.commit()

2 个答案:

答案 0 :(得分:0)

尝试dict.update

>>> d = dict(a=23, b=42, c=None)                                                                                                                                                              
>>> d                                                                                                                                                                                         
{'a': 23, 'b': 42, 'c': None}                                                                                                                                                                 
>>> d.update({'a' : 'foobar'})                                                                                                                                                                
>>> d                                                                                                                                                                                         
{'a': 'foobar', 'b': 42, 'c': None}

答案 1 :(得分:0)

在必填字段上循环,而不是响应中字典的键。然后在新词典中分配值时使用if/else

response_data_2 = {key: (response_data[value] if key in response_data else None) for value in required_fields}