0

Was wondering if something like the following was possible:

rarity = {>= 75: 'Common', <= 20 : 'Rare', >= 5: 'Legendary'}
rook
  • 5,880
  • 4
  • 39
  • 51

3 Answers3

1

In Python 2.7 this will raise a syntax error. It feels like abuse of dictionary (key-value storage) concept. Maybe you should rework your code and you could use 'Common', 'Rare' as keys and values as ranges, i.e. range(5,20), range(20), etc.

rook
  • 5,880
  • 4
  • 39
  • 51
1

This cannot be done with dict in python. You probably need an ordinary function for your task:

def check(x):
    if x >= 75:
        return 'Common'
    if x <= 20:
        ...

Remember that order of checks and return statements matters.

Ivan Vinogradov
  • 4,269
  • 6
  • 29
  • 39
  • the question is very unclear but there are ways to use a dict like this e.g. `x = 6; {x >= 75: 'Common', x<= 20 : 'Rare', x>= 5: 'Legendary'}[True]` – Chris_Rands Jun 01 '18 at 14:45
  • 1
    @Chris_Rands except OP has made a mistake, for Rare it should be `x>=20` and if you use that in your code you'll see only the last true condition will be returned. So your code will fail for `x=25` – anishtain4 Jun 01 '18 at 14:54
  • @anishtain4 We can only guess what the question is about but assuming a single output for a single integer input (also assumed in Ivan's code), it could be done in a dict like I showed above – Chris_Rands Jun 01 '18 at 15:02
  • 1
    @Chris_Rands yes, this is a very poorly written question. However it's clear that OP is looking for a short form of switch. I don't see any reason for a switch command generally, `if ... elif` does the same job. – anishtain4 Jun 01 '18 at 15:19
1

I can't see a way to do this with better than O(k) performance, where k is the number of keys in your sort-of dict.

If you are not seeking dict's O(1) performance, and just want a dict-like syntax, you can implement a mapping object yourself, like so:

from collections.abc import Mapping

class CallDict(Mapping):
    def __init__(self, *pairs):
        self._pairs = pairs
    def __iter__(self):
        return iter(())
    def __len__(self):
        return len(self._pairs)
    def __getitem__(self, x):
        for func, value in self._pairs:
            if func(x):
                return value
        raise KeyError("{} satisfies no condition".format(x))

# Conditions copied directly from OP, but probably wrong.
cd = CallDict(
    ((lambda x: x >= 75), "Common"),
    ((lambda x: x <= 20), "Rare"),
    ((lambda x: x >= 5), "Legendary"),
)


assert cd[1] == 'Rare'
assert cd[10] == 'Rare'
assert cd[50] == 'Legendary'
assert cd[100] == 'Common'
Robᵩ
  • 163,533
  • 20
  • 239
  • 308
  • 1
    Note that I don't advocate creating a `Mapping` object for this particular case. For such a simple case, I'd prefer to see `rarity = HowRareIsIt(10)`. But knowing that one *can* create a mapping object may be useful for other, similar, cases. – Robᵩ Jun 01 '18 at 14:59