0
votes

So I Have a set of dicts (this is a sample) see the code below for the full set

{
"XETHXXBT": {
"altname": "ETHXBT",
"wsname": "ETH/XBT",
"aclass_base": "currency",
"base": "XETH",
"aclass_quote": "currency",
"quote": "XXBT",
"lot": "unit",
"pair_decimals": 5,
"lot_decimals": 8,
"lot_multiplier": 1,
"leverage_buy": [
2,
3,
4,
5
],
"leverage_sell": [
2,
3,
4,
5
],
"fees": [
[],
[],
[],
[],
[],
[],
[],
[],
[]
],
"fees_maker": [
[],
[],
[],
[],
[],
[],
[],
[],
[]
],
"fee_volume_currency": "ZUSD",
"margin_call": 80,
"margin_stop": 40,
"ordermin": "0.005"
},
"XXBTZUSD": {
...
"ordermin": "0.0002" }}

I would like to return the full dict when a key within matches.

I keep running into key errors when using:

import krakenex
kex = krankenex.API()
assets = kex.query_public('AssetPairs')
a = {x for x in assets if assets[x]['wsname'] == 'XBT/USD'}

I thought this was the 'pythonic' way of doing this sort of thing, but perhaps I am missing a step?

As per comment from @He3lixxx this seems to do the trick

a = {x for x in assets.keys() if assets[x].get('wsname') == 'XBT/USD'}

And is there a good general advice tag for answers because I should definitely be better about using try/except blocks?

2
a = {x for x in assets.keys() if assets[x].get('wsname') == 'XBT/USD'} should do the trickHe3lixxx
This did the trick, thank you very much!Matt

2 Answers

2
votes

Maybe just use exceptions:

a = []

for x in assets:
    try:
        if x['wsname']:
            a.append(x)
    except KeyError:
        pass

Tip/reminder: for debugging, you can use

except KeyError as error_info:
    print(error_info)

It will give you the full error message.

You might ask

Why should I use this, when I remove the exception, it will give me the error anyways?!

The answer is: this will ignore the error, so the program won't stop.

Hope this helps ;)

1
votes

Yes, indeed, the dict comprehension you wrote down is pythonic. However, even in such a comprehension, you need to watch out: If you do anything "bad", the same consequences will happen. So, if you access a dictionary with an invalid key, this will raise an IndexError.

You can circumvent this using the dict.get method, which takes a dictionary key and by default returns None if this key was not found. Since None will always be inequal to the string you are searching, we can happily take this:

a = {x for x in assets if assets[x].get('wsname') == 'XBT/USD'}

(In my comment, I additionally used assets.keys() to iterate over the keys. This is a bit more verbose and doesn't leave any doubt what we're iterating over, for x for x in assets does exactly the same.)