What does & mean in python [duplicate] - python

This question already has answers here:
Bitwise operation and usage
(17 answers)
Closed 10 months ago.
I came across the following code
numdigits = len(cardNumber)
oddeven = numdigits & 1
what exactly is going on here? I'm not sure what the "&" is doing.

Answer
The & symbol is a bitwise AND operator. Used with 1, it basically masks the value to extract the lowest bit, or in other words will tell you if the value is even or odd.
More Info on Python's & operator
For more information, see: http://wiki.python.org/moin/BitwiseOperators
Why it Works to check Odd vs. Even
EDIT: Adding this section since this answer is getting some love
The reason why ANDing a value with 1 tells if the value is odd or even may not be obvious at first.
The binary representation of a number is essentially the sum of a series of YES or NO for each power of 2 moving leftward starting in the rightmost digit with 1, 2, 4, 8, ...
There is only one way to represent any number in this way. E.g. the number 13 (base 10) can be written in binary as "1101" (or hexadecimal as 0xD, but that's beside the point). See here:
1 1 0 1
x x x x
8 4 2 1
= = = =
8 + 4 + 0 + 1 = 13
Notice that aside from the rightmost binary digit, all other 1 digits will add an even number (i.e. a multiple of 2) to the sum. So the only way to get an odd final sum is to add that odd 1 from the rightmost digit. So if we're curious if a number is odd or even, we can look at its binary representation and ignore everything except for the rightmost digit.
To do this, we use the bitwise AND operator. The value 1 in binary is expressed as 1:
0 0 0 1
x x x x
8 4 2 1
= = = =
0 + 0 + 0 + 1 = 1
ANDing a value with 1 like this will result in 1 if the value's rightmost bit is set, and 0 if it is not.
And because 0 is generally considered "false" in most languages, and non-zero values considered "true", we can simply say as a shortcut:
if (value & 1): do_something_with_odd_value()...

& is also used for taking the intersection of two Python sets:
set1 = {0,1,2,3}
set2 = {2,3,4,5}
print(set1 & set2)
>>>set([2, 3])
More generally, Python allows operator overloading, meaning you can write classes that re-interpret what the & operator does. This is how libraries such as Pandas and Numpy hijack &.

It's a bitwise operation, in this case assigning zero to oddeven if cardNumber has an even number of elements (and one otherwise).
As an example: suppose len(cardNumber) == 235. Then numdigits == 235, which is 0b11101011 in binary. Now 1 is '0b00000001' in binary, and when you "AND" them, bitwise, you'll get:
11101011
&
00000001
----------
= 00000001
Similarly, if numdigits were 234, you would get:
11101010
&
00000001
----------
= 00000000
So, it's basically a obfuscated way of checking if len(cardNumber) % 2. Probably written by someone with a C background, because it is not very pythonic - readability counts!

& is a bitwise and, which is an efficient way to do bit-level calculations. It is taking numdigits and and-ing it with 1, bit-by-bit.

It's a binary bitwise AND operator.

Related

Finding the set of n-bit integers related to a given integer by single bit 'hopping'

Given an n-bit integer, I want to find the set of n-bit integers which are related to my original integer by the interchange of a single 1 by a single 0 where the interchanged 1 and 0 must be adjacent
So what I want is to find some function such that for example, if I gave it the binary 1011 (11 in base 10) it returns 0111 and 1101 (7 and 13 in base 10)
ie. so this would look like:
>>> bit_hop(11, n=4)
[7, 13]
It's important that this function knows how many bits the number is because my other constraint is that I need this to have periodic boundary conditions such that for example 0111 would return not only 1011 but also 1110, ie. the edges of the binary number should be adjacent.
Also, as said, only one swapping should be allowed per hop. This means that bit_hop(1010) should return [1100, 0011, 1001, 0110]
Does anyone have any ideas on how one might go about doing this? I know that this should involve some clever usage of the >>, << and ^ operations but I'm having trouble seeing the synthesis.
To do this directly in binary, you have to notice a couple of things about the algorithm. First it always deals with adjacent bits, except for looping around from the first bit to the last. Second those bits must be different, if they're the same swapping them wouldn't do anything.
This code walks a 2-bit mask around the value and tests to see if the bits are different, then uses exclusive-or to swap them.
def bit_hop(x, n):
for i in range(n-1):
mask = 3 << i
if x & mask != 0 and x & mask != mask:
yield x ^ mask
mask = (1 << (n-1)) | 1
if x & mask != 0 and x & mask != mask:
yield x ^ mask

What is the interpreter really seeing and executing for bitwise operators?

I am trying to understand bitwise operators in Python 2.7 (<<, >>, &, |, ~ and ^), so my question is: what is the interpreter really seeing and executing? When:
>>> 3 >> 0
3
>>> 3 >> 1
1
and why
>>> 3 >> 2
0
and after that if you increment the second number by one the answer will continue to be 0.
They treat it as if it were a string of bits, written in twos-complement binary. But I do not understand what happens here.
Have a look at the binary representation of these numbers and imagine that there are infinite zeroes to the left:
...0000011 = 3
Now, what >> does is it shifts the binary representation to the right. This is the same as deleting the last digits:
If you shift by 0 places, nothing changes. Therefore, 3 >> 0 is 3.
If you shift by 1 place, you delete the last binary digit:
...0000011 >> 1 = ...000001 = 1
Therefore, 3 >> 1 is 1.
If you shift by 2 or more places, all of the binary ones will be deleted and you are left with only zeroes:
...0000011 >> 2 = ...00000 = 0
This is why 3 >> 2 (or more than 2) is always 0.

My answer is changing with the same code [duplicate]

This question already has answers here:
Why does integer division yield a float instead of another integer?
(4 answers)
Closed 5 months ago.
I am a complete python beginner and I am trying to solve this problem :
A number is called triangular if it is the sum of the first n positive
integers for some n For example, 10 is triangular because 10 = 1+2+3+4
and 21 is triangular because 21 = 1+2+3+4+5+6. Write a Python program
to find the smallest 6-digit triangular number. Enter it as your
answer below.
I have written this program:
n = 0
trinum = 0
while len(str(trinum)) < 6:
trinum = n*(n+1)/2
n += 1
print(trinum)
And it only works in the python I have installed on my computer if I say while len(str(trinum)) < 8: but it is supposed to be while len(str(trinum)) < 6:. So I went to http://www.skulpt.org/ and ran my code there and it gave me the right answer with while len(str(trinum)) < 6: like it's supposed to. But it doesn't work with 6 with the python i have installed on my computer. Does anyone have any idea what's going on?
Short Answer
In Python 3, division is always floating point division. So on the first pass you get something like str(trinum) == '0.5'. Which isn't what you want.
You're looking for integer division. The operator for that is //.
Long Answer
The division operator changed in Python 2.x to 3.x. Previously, the type of the result was dependent on the arguments. So 1/2 does integer division, but 1./2 does floating point division.
To clean this up, a new operator was introduced: //. This operator will always do integer division.
So in Python 3.x, this expression (4 * 5)/2 is equal to 10.0. Note that this number is less than 100, but it has 4 characters in it.
If instead, we did (4*5)//2, we would get the integer 10 back. Which would allow your condition to hold true.
In Python 2, the / operator performs integer division when possible: "x divided by y is a remainder b," throwing away the "b" (use the % operator to find "b"). In Python 3, the / operator always performs float division: "x divided by y is a.fgh." Get integer division in Python 3 with the // operator.
You have two problems here, that combine to give you the wrong answer.
The first problem is that you're using /, which means integer division in Python 2 (and the almost-Python language that Skulpt implements), but float division in Python 3. So, when you run it on your local machine with Python 3, you're going to get floating point numbers.
The second problem is that you're not checking for "under 6 digits" you're checking for "under 6 characters long". For positive integers, those are the same thing, but for floats, say, 1035.5 is only 4 digits, but it's 6 characters. So you exit early.
If you solve either problem, it will work, at least most of the time. But you really should solve both.
So:
n = 0
trinum = 0
while trinum < 10**6: # note comparing numbers, not string length
trinum = n*(n+1)//2 # note // instead of /
n += 1
print(trinum)
The first problem is fixed by using //, which always means integer division, instead of /, which means different things in different Python versions.
The second problem is fixed by comparing the number as a number to 10**6 (that is, 10 to the 6th power, which means 1 with 6 zeros, or 1000000) instead of comparing its length as a string to 6.
Taking Malik Brahimi's answer further:
from itertools import *
print(next(dropwhile(lambda n: n <= 99999, accumulate(count(1))))
count(1) is all the numbers from 1 to infinity.
accumulate(count(1)) is all the running totals of those numbers.
dropwhile(…) is skipping the initial running totals until we reach 100000, then all the rest of them.
next(…) is the next one after the ones we skipped.
Of course you could argue that a 1-liner that takes 4 lines to describe to a novice isn't as good as a 4-liner that doesn't need any explanation. :)
(Also, the dropwhile is a bit ugly. Most uses of it in Python are. In a language like Haskell, where you can write that predicate with operator sectioning instead of a lambda, like (<= 99999), it's a different story.)
The division method in Py2.x and 3.x is different - so that is probably why you had issues.
Just another suggestion - which doesn't deal with divisions and lengths - so less buggy in general. Plus addition is addition anywhere.
trinum = 0
idx =0
while trinum < 99999: #largest 5 digit number
idx += 1
trinum += idx
print trinum
import itertools # to get the count function
n, c = 0, itertools.count(1) # start at zero
while n <= 99999:
n = n + next(c)

append 2 hex values in python

I am trying to append some hex values in python and I always seem to get 0x between the number. From what I searched, either this is not possible without converting it into a lit of values ?? I am not sure.
a = 0x7b
b = 0x80000
hex(a) + hex(b) = 0x7b0x80000
I dont want the 0x in the middle - I need, 0x7b80000. is there any other way to do this? If I convert to integer I get the sum of the two and converting it to hex is a different value than 0x7b80000
I don't think you want to "append" them. Doing integer arithmetic by using strings is a bad idea. I think you want to bit-shift a into the right place and OR them together:
>>> a = 0x7B
>>> b = 0x80000
>>>
>>> hex( (a<<20) | b )
'0x7b80000'
Perhaps if you were more specific about what these numbers are and what exactly you're trying to accomplish I could provide a more general answer.
You can use f-string formatting with Python 3:
>>> a = 0x7b
>>> b = 0x80000
>>> f'0x{a:x}{b:x}'
'0x7b80000'
This is a more generic way to append hex / int / bin values.
Only works for positive values of b.
a = 0x7b
b = 0x80000
def append_hex(a, b):
sizeof_b = 0
# get size of b in bits
while((b >> sizeof_b) > 0):
sizeof_b += 1
# align answer to nearest 4 bits (hex digit)
sizeof_b += sizeof_b % 4
return (a << sizeof_b) | b
print(hex(append_hex(a, b)))
Basically you have to find the highest set bit that b has.
Align that number to the highest multiple of 4 since that's what hex chars are.
Append the a to the front of the highest multiple of 4 that was found before.
It's been 7 years but the accepted answer is wrong and this post still appears in the first place in google searches; so here is a correct answer:
import math
def append_hex(a, b):
sizeof_b = 0
# get size of b in bits
while((b >> sizeof_b) > 0):
sizeof_b += 1
# every position in hex in represented by 4 bits
sizeof_b_hex = math.ceil(sizeof_b/4) * 4
return (a << sizeof_b_hex) | b
The accepted answer doesn't make sense (you can check it with values a=10, b=1a). In this solution, we search for the nearest divider of 4 - since every hex value is represented by 4 bits - and then move the first value this time of bits.

What is the double inequality (>>) sign in python? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Python - '>>' operator
There's some code that does this:
x = n - 1 >> 1
I don't know if I have to provide more syntax, but what does the >> mean? I've been searching all over, but can't find any explanation.
Its a shift right logical, it is a bitwise operation that tells the number to shift in bits by that amount. In this case you are shifting by 1, which is equivalent to dividing by 2.
If you do not understand bitwise operations, a simple conversion for you to remember would be this.
x >> n
is equivalent to
x // (2**n)
It is the bitwise shift-to-right operator.
It shifts the bits of the integer argument to the right by the number on the right-hand side of the expression:
>>> 8 >> 2
2
or illustrated in binary:
>>> bin(0b1000 >> 2)
'0b10'
Your code example is actually doubly confusing as it mixes arithmetic and bitwise operations. It should use the '//' integer division operation instead:
x = (n - 1) // 2
x >> y
is equivalent to
x.__rshift__(y)
which, as others have said, is meant to be a bitshift.
>> is the bitwise right shift operator. This operator move all bits in the first operand right by the second operand.
So: a >> b = a // 2**b
Example:
36 in binary is 0b100100
36 >> 1 is 0b10010 (last binary digit or "bit" is removed) which is 18
36 >> 2 is 0b1001 (2 bits removed) which is 9
Note that the operator goes after addition. So the code does n-1 first, then right shift it by 1 bit (i.e. divides by 2).

Categories

Resources