-2

I have code that looks like this

'''

phi = (QubitOperator('X0') + 
       QubitOperator('Y0') +
       QubitOperator('Z0') + 
       QubitOperator('X1') +
       QubitOperator('Y1') +
       QubitOperator('Z1') )

'''

where QubitOperator is a command in a package I am using. How can I automate this to iterate over X Y and Z and 0, 1, 2.... and create phi?

  • 1
    It looks like you might be looking for something like `functools.reduce(operator.add, (QubitOperator(f'{a}{n}') for a,n in itertools.product(["X", "Y", "Z"], range(10))))` – alani Aug 12 '20 at 23:22
  • 1
    @alaniwi `functools.reduce(operator.add, ...)` -> `sum(...)` – juanpa.arrivillaga Aug 12 '20 at 23:29
  • @juanpa.arrivillaga Ah yes, good point :-) – alani Aug 12 '20 at 23:30
  • 1
    @juanpa.arrivillaga Actually no, I stand by my original: `sum` only works if we know that the values are numeric. (Just tried it with string concatenation.) – alani Aug 12 '20 at 23:32
  • @alaniwi no, it works, the developers just prevent you from shooting yourself in the foot and using the unnecessarily quadratic time algorithm (sequence concatenation). It's just as bad if you do it with `reduce(operator.add, ...)`. But that's a special case for strings only, because too many people do that, and they shouldn't. – juanpa.arrivillaga Aug 12 '20 at 23:38
  • 1
    @juanpa.arrivillaga String concatenation was only an example. Just tried it with a custom class that has an `__add__` method, and it works with `reduce(add, ...)` but not with `sum(...)` – alani Aug 12 '20 at 23:43
  • 1
    Yes it does, you just need to provide a suitable starting value, e.g. `sum(list_of_custom_objects, Foo())` – juanpa.arrivillaga Aug 12 '20 at 23:44
  • @juanpa.arrivillaga Yes you're right. – alani Aug 12 '20 at 23:49

1 Answers1

0

your existing code may be cleaner, but supposing you had to do this for more than 8 elements:

from functools import reduce

letters = ['X', 'Y', 'Z']
numbers = ['0', '1', '2']
pairs = [f'{l}{n}' for l in letters for n in numbers]
# this gets you ['X0', 'X1', 'X2', 'Y0', ..., 'Z2']
qubits = [QubitOperator(x) for x in pairs]
# not sure the best way to get this into a single phi. join seems logical, but probably doesn't work.
phi = reduce(lambda acc, cur: acc + cur, pairs)

Overview of the code:

  1. The first three lines basically just define the data and merge them together. the list comprehension is kind of 2-layered (unofficial term), so it'll iterate over letters, then iterate over numbers until all 9 elements are reached
  2. line 4 (beginning qubits = [... wraps each of the strings created in pairs inside a QubitOperator. Technically not needed, and I'd probably put it in line 3 if I were coding for myself.
  3. Line 5, as noted, is not necessarily the best way of doing this, but it was the best I could think of. reduce basically allows you to compress a list of stuff into something else -- in this case, we're going to concatenate everything into phi. This will iterate over the list of qubits and add them together. Expanding this out gets something close to what you've already done: QubitOperator('X0') + QubitOperator('X1')+... As a commenter pointed out, a for loop may work as well in this scenario. That code looks like:
phi = qubits[0]
for i in range(1, len(qubits)):
  phi = phi + qubits[i]

There is a caveat here: I'm not 100 percent sure this is going to work. Every step prior to the last one should, and I think the last step should as well, but without any testing, it's hard to know.

Also, as you can see, we effectively turned 8 lines of straight forward code into 4 lines of relatively complex code. I'm not sure that tradeoff is worth it, unless you have a lot of data, or otherwise you need to repeat this process frequently with fresh data.

Hikash
  • 419
  • 3
  • 6
  • `reduce(lambda x, y: x + y, ...)` -> `sum(...)` ... or just a for-loop. – juanpa.arrivillaga Aug 12 '20 at 23:39
  • I'm not sure I'd recommend using `sum` here as it's confusing, plus as other commenters have pointed out, it may not work in some instances. Since I do not know if it'll work in this situation, I'm opting to not revise the answer. As for a for loop, that may work, but I prefer `reduce` over a loop in this scenario. – Hikash Aug 12 '20 at 23:47
  • how is `sum(...)` any more or less confusing than `reduce(...)`? – juanpa.arrivillaga Aug 12 '20 at 23:48
  • Because `sum` implies adding numbers. I don't really know what else to say. It's more confusing to me, hence, I'm opting not to include it. Feel free to create your own answer. – Hikash Aug 12 '20 at 23:53
  • @tdelaney no, it doesn't. – juanpa.arrivillaga Aug 12 '20 at 23:56
  • Here's the golfed solution you're looking for: `ϕ=sum([QubitOperator(x) for x in [f'{l}{n}' for l in 'XYZ' for n in [1,2,3]]])` No guarantee this will work. – Hikash Aug 13 '20 at 00:07