Reputation: 542
I have two functions that are very similar:
def hier_group(self):
if self.sku:
return {f"{self.hierarchic}": f"${self.hierarchic}", "id": "$id", "ix": "$ix"}
else:
return {f"{self.hierarchic}": f"${self.hierarchic}", "ix": "$ix"}
def hier_group_merge(self):
if self.sku:
return {f"{self.hierarchic}": f"${self.hierarchic}", "id": "$id"}
else:
return {f"{self.hierarchic}": f"${self.hierarchic}"}
I am trying to reduce into 1 function that has only one if/else.
The only difference in both functions is "ix": "$ix"
.
What I am trying to do is the following:
def hier_group(self, ix=True):
if self.sku:
return {f"{self.hierarchic}": f"${self.hierarchic}", "id": "$id" f'{',"ix": "$ix"' if ix == True else ""}'}
else:
return {f"{self.hierarchic}": f"${self.hierarchic}" f'{',"ix": "$ix"' if ix == True else ""}'}
But it's getting trick to return , "ix": "$ix"
.
Upvotes: 0
Views: 42
Reputation: 532093
Build a base dictionary, then add keys as appropriate.
def hier_group(self, ix=True):
d = { f'{self.hierarchic}': f'${self.hierarchic}' }
if self.sku:
d['id'] = '$id'
if ix:
d['ix'] = '$ix'
return d
However, there are many who believe using two functions, rather than having one function behave like two different functions based on a Boolean argument, is preferable.
def hier_group(self):
d = { f'{self.hierarchic}': f'${self.hierarchic}' }
if self.sku:
d['id'] = '$id'
return d
def hier_group_with_ix(self):
d = self.hier_group()
d.update('ix': '$ix')
return d
You might also use a private method that takes an arbitrary list of attribute names.
# No longer needs self, so make it a static method
@staticmethod
def _build_group(attributes):
return {f'{x}: f'${x} for x in attributes}
def build_group(self, ix=True):
attributes = [self.hierarchic]
if ix:
attributes.append('ix')
if self.sku:
attributes.append('id')
return self._build_group(attributes)
You will probably ask: why is using a Boolean attribute here OK? My justification is that you aren't really altering the control flow
of build_group
with such an argument; you are using it to
build up a list of explicit arguments for the private method. (The dataclass
decorator in the standard library takes a similar approach: a number of Boolean-valued arguments to indicate whether various methods should be generated automatically.)
Upvotes: 2
Reputation: 24279
You can avoid repeating common parts:
def hier_group(self, ix=True):
out = {f"{self.hierarchic}": f"${self.hierarchic}"}
if self.sku:
out["id"] = "$id"
if ix:
out["ix"] = "$ix"
Upvotes: 1