#๐ Need Help with converting the function to use dicts instead of if-else blocks
69 messages ยท Page 1 of 1 (latest)
@full linden
Remember to:
- Ask your Python question, not if you can ask or if there's an expert who can help.
- Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
- Explain what you expect to happen and what actually happens.
:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.
@gray skiff
Thank you in advance for the help.
So, I have this code, fully functional, but it's just sooo long with all the if-else blocks, and would like to make it as short and simple as possible, more pythonic in a sense.
Right now, all the dict approaches I tried become massive, and just make the code harder to read than making it shorter.
the first low-hanging fruit i noticed is this series of if statements here
in which, you could use a dict
Case in point
give me a sec to type it out
Of course, please take your time.
wait hold on
Yes?
what are circ.X, circ.Y, etc.?
like their types
i need to know if they are hashable
Oh, they're methods.
Actually, they could be treated as objects as well.
Like I can use them as an object.
class _PauliX(Pauli, common_gates.XPowGate):
def __init__(self):
Pauli.__init__(self, index=0, name='X')
common_gates.XPowGate.__init__(self, exponent=1.0)
def __pow__(self, exponent: 'cirq.TParamVal') -> common_gates.XPowGate:
return common_gates.XPowGate(exponent=exponent) if exponent != 1 else _PauliX()
def _with_exponent(self, exponent: 'cirq.TParamVal') -> common_gates.XPowGate:
return self.__pow__(exponent)
@classmethod
def _from_json_dict_(cls, exponent, global_shift, **kwargs):
assert global_shift == 0
assert exponent == 1
return Pauli._XYZ[0]
@property
def basis(self) -> Dict[int, '_XEigenState']:
from cirq.value.product_state import _XEigenState
return {+1: _XEigenState(+1), -1: _XEigenState(-1)}
X = _PauliX()
you could do something like this pattern
if_true is a mapping from your parameters['sub_gate'] field to functions
you could also apply that to a few of the other if/else's below it
I am sort of aiming for sth like what I did here:
def convert(self,
circuit_framework: Type[Circuit]) -> Circuit:
converted_circuit = circuit_framework(self.num_qubits, self.num_clbits)
gate_mapping: dict[str, Callable] = {
'RX': converted_circuit.RX,
'RY': converted_circuit.RY,
'RZ': converted_circuit.RZ,
'H': converted_circuit.H,
'X': converted_circuit.X,
'Y': converted_circuit.Y,
'Z': converted_circuit.Z,
'S': converted_circuit.S,
'T': converted_circuit.T,
'U3': converted_circuit.U3,
'SWAP': converted_circuit.SWAP,
'CX': converted_circuit.CX,
'CY': converted_circuit.CY,
'CZ': converted_circuit.CZ,
'CH': converted_circuit.CH,
'CS': converted_circuit.CS,
'CT': converted_circuit.CT,
'CRX': converted_circuit.CRX,
'CRY': converted_circuit.CRY,
'CRZ': converted_circuit.CRZ,
'CU3': converted_circuit.CU3,
'CSWAP': converted_circuit.CSWAP,
'MCX': converted_circuit.MCX,
'MCY': converted_circuit.MCY,
'MCZ': converted_circuit.MCZ,
'MCH': converted_circuit.MCH,
'MCS': converted_circuit.MCS,
'MCT': converted_circuit.MCT,
'MCRX': converted_circuit.MCRX,
'MCRY': converted_circuit.MCRY,
'MCRZ': converted_circuit.MCRZ,
'MCU3': converted_circuit.MCU3,
'MCSWAP': converted_circuit.MCSWAP,
'GlobalPhase': converted_circuit.GlobalPhase,
'measure': converted_circuit.measure
}
for gate_info in self.circuit_log:
gate_name = gate_info['gate']
gate_info = dict(list(gate_info.items())[1:])
gate_mapping[gate_name](**gate_info)
return converted_circuit
All of this is to basically avoid having if-else blocks.
Yes, Python doesnt have Rust's much cleaner match which would be a perfect application for this
Which is unfortunate
But I am also learning what is considered "pythonic", so please let me know if the one you shown is considered good practice and I can adapt that.
Hehe, I'll consider making the package I have later in Rust as well.
"Pythonic" is subjective but it generally just means doing things in a way that takes advantage of the language's unique characteristic
characteristics*
Yeah.
for example, functions are first class objects
So since you have a long chain of if/else's where you just call different functions, have a mapping from conditions to functions instead
Which you've already done
My code example earlier simply replicates the additional logic you have of also checking for the len(parameters['control_qid_shape'])
Yeah, but in this one that we're talking about now issue is the inconsistency of the parameters passed and the nested ifs.
But it follows the same general pattern that you've shown in that latest codeblock
Yeah, I guess some if-else blocks become inevitable.
Is yours inside the loop?
or outside?
I am sort of considering using lambda to define the dict outside once, instead of defining it everytime inside the loop.
It's in the same context as everything under your "elif gate_type == 'ControlledGate'"
So it's inside the loop
I don't see why you can't already have the mapping dict outside the loop?
circuit already exists before the loop, right?
Yes, but wouldn't it be re-defining the dict everytime?
Like
x = 1
vs
for _ in range(10):
x = 1
Yes, if it were inside the loop
But I'm saying, you can have it outside the loop already
With how your code is
given that circuit exists outside the loop
So everything you need to map to, i.e. circuit's methods, already exist
For this codeblock, I don't think you need a mapping dict
It's small, and you have one outlier case being ZPowGate which would be awkward having to have an if-statement separate from the mapping since there's no way to cleanly fit the logic for ZPowGate inside the mapping without defining an external function (unnecessary complexity) or having an obnoxiously long lambda
Anyway, seems you have Opal helping you already
I'm going to have dinner
Yeah, he also agrees with this dict thing being weird for this case.
This help channel has been closed and it's no longer possible to send messages here. If your question wasn't answered, feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.