MartinThoma / flake8-simplify

❄ A flake8 plugin that helps you to simplify code
MIT License
185 stars 19 forks source link

SIM116: Use a dictionary instead many if/elif equality checks #31

Closed MartinThoma closed 3 years ago

MartinThoma commented 3 years ago

Explanation

Example

# Bad
if a == "foo":
    return "bar"
elif a == "bar":
    return "baz"
elif a == "boo":
    return "ooh"
else:
    return 42

# Good
mapping = {"foo": "bar", "bar": "baz", "boo": "ooh"}
return mapping.get(a, 42)
MartinThoma commented 3 years ago
        If(
            test=Compare(
                left=Name(id='a', ctx=Load()),
                ops=[Eq()],
                comparators=[Constant(value='foo', kind=None)],
            ),
            body=[
                Return(
                    value=Constant(value='bar', kind=None),
                ),
            ],
            orelse=[
                If(
                    test=Compare(
                        left=Name(id='a', ctx=Load()),
                        ops=[Eq()],
                        comparators=[Constant(value='bar', kind=None)],
                    ),
                    body=[
                        Return(
                            value=Constant(value='baz', kind=None),
                        ),
                    ],
                    orelse=[
                        If(
                            test=Compare(
                                left=Name(id='a', ctx=Load()),
                                ops=[Eq()],
                                comparators=[Constant(value='boo', kind=None)],
                            ),
                            body=[
                                Return(
                                    value=Constant(value='ooh', kind=None),
                                ),
                            ],
                            orelse=[
                                Return(
                                    value=Constant(value=42, kind=None),
                                ),
                            ],
                        ),
                    ],
                ),
            ],
Effervex commented 2 years ago

This style guideline may result in better looking code, but it is inefficient and can even create errors. Each dict value is interpreted whenever the dict is evaluated.

For example:

some_array = [0,1] if x else [0,1,2]
mapping = {
  "foo": "bar",
  "foo2": long_expensive_function()
  "foo3": three_arg_func(some_array[0], some_array[1], some_array[2])
}
return mapping.get("foo",42) # This will still evaluate "foo2", and if x is True, completely crash when evaluating "foo3"

Edit: I created a new issue and referenced this.