Hello all -

I've been coding in Python for a couple of months now, and I recently ran across the following piece of code (where x is a set or list):

f = lambda x: [[y for j, y in enumerate(x) if (i >> j) & 1] for i in range(2**len(x))]

I was hoping someone could explain to me the following components:

1. 'y for j': after doing some reading, I think I understand the basic principles of * for *, but I still don't think I get exactly what Python is doing.

2. '(i >> j) & 1': I read something somewhere about shifting with '>>', but quite frankly, I'm still completely clueless. Also, I'm very new to bitwise operators and could use some explanation.


It may be easier to understand when you take comprehensions out.

def myfunc(x):
	ret = []
	for i in range(2**len(x)):
		res = []
		for j, y in enumerate(x):
			if (i >> j) & 1:
	return ret

Thanks jcao; that definitely clears things up a bit.
I guess my real problem, then, is understanding line 6 of your code. As I said, I'm really not clear on the functionality of '>>' or '&'.

Thanks again,

Oh okay, so in Python the '>>' is an arithmetic RIGHT-SHIFT and the '&' is logical AND.

So AND is like this:
0 AND 0 = 0
0 AND 1 = 0
1 AND 1 = 1

So let's say you have two numbers: 42, 27

>>> bin(42)
>>> bin(27)

To AND them, you align them:

So that gives you 1010, you do int('1010',2) and you get your result:

You can check, 42 & 27 .

Now, right shift:

Let's say you have binary
Then right shift by 1 (44 >> 1)
would be move all the digits right, so it becomes 0101100 (empty space is filled with 0)

right shift by 2 would make it 001011.

Ah. Thank you. The code makes a lot more sense now.
Sorry for not clarifying this before, but I have one more question:
This code was brought up in the context of returning all possible sub multi-sets of a list x, so what does the bitwise comparison have to do with that?

Thanks so much for all of your prompt responses,

I'm not sure, perhaps it's some algorithm?