Питон бит и (&) против и
Привет всем, у меня есть эта часть кода:
for line in response.body.split("\n"):
if line != "":
opg = int(line.split(" ")[2])
opc = int(line.split(" ")[3])
value = int(line.split(" ")[5])
if opg==160 & opc==129:
ret['success'] = "valore: %s" % (value)
self.write(tornado.escape.json_encode(ret))
У меня есть серия, если линия типа
1362581670 2459546910990453036 156 0 30 0
Я хочу взять только строку, где третий и четвертый элемент соответственно 160 и 129. Этот код не работает. Должен ли я делать кастинг? Я думаю, что opg==160 работает над сбором int с int...
3 ответа
Вы запутались с операторами; and
правильный логический тест, &
вместо этого это двоичный побитовый оператор:
if opg == 160 and opc == 129:
В качестве числового оператора &
Оператор имеет более высокий приоритет, чем операторы сравнения, в то время как логические операторы имеют более низкий приоритет. Выражение opg == 160 & opc == 129
таким образом, интерпретируется как opg == (160 & opc) == 129
вместо этого, что, вероятно, не то, что вы хотели.
Вы можете несколько упростить свой код:
for line in response.body.splitlines():
if line:
line = map(int, line.split())
opg, opc, value = line[2], line[3], line[5]
if opg == 160 and opc == 129:
ret['success'] = "valore: %s" % (value)
self.write(tornado.escape.json_encode(ret))
Просто используйте line.split()
вместо line.split(" ")
, Таким образом, он обрабатывает любые типы пробелов. Если это не просто пробелы, вы получите странные результаты, которые могут быть тем, что происходит.
&
это побитовая операция. Вы, вероятно, хотите and
, С целыми числами вы можете не думать, что это будет иметь значение
>>> True & False
False
>>> True & True
True
>>> False & False
False
Тем не менее, обратите внимание, что &
а также and
имеют разные приоритеты.
>>> opc,opg = 160,129
>>> opc == 160 & opg == 129
False
>>> opc == 160 and opg == 129
True
В принципе, &
крепче, чем ==
, так a == b & c == d
анализируется как a == ( b & c) == d
скорее, чем (a == b) & (c == d)
как ты и хотел.
>>> def func1():
... opc,opg = 160,129
... opc == 160 & opg == 129
...
>>> def func2():
... opc,opg = 160,129
... opc == 160 and opg == 129
...
>>> import dis
>>> dis.dis(func1)
2 0 LOAD_CONST 3 ((160, 129))
3 UNPACK_SEQUENCE 2
6 STORE_FAST 0 (opc)
9 STORE_FAST 1 (opg)
3 12 LOAD_FAST 0 (opc)
15 LOAD_CONST 1 (160)
18 LOAD_FAST 1 (opg)
21 BINARY_AND
22 DUP_TOP
23 ROT_THREE
24 COMPARE_OP 2 (==)
27 JUMP_IF_FALSE_OR_POP 39
30 LOAD_CONST 2 (129)
33 COMPARE_OP 2 (==)
36 JUMP_FORWARD 2 (to 41)
>> 39 ROT_TWO
40 POP_TOP
>> 41 POP_TOP
42 LOAD_CONST 0 (None)
45 RETURN_VALUE
>>> dis.dis(func2)
2 0 LOAD_CONST 3 ((160, 129))
3 UNPACK_SEQUENCE 2
6 STORE_FAST 0 (opc)
9 STORE_FAST 1 (opg)
3 12 LOAD_FAST 0 (opc)
15 LOAD_CONST 1 (160)
18 COMPARE_OP 2 (==)
21 JUMP_IF_FALSE_OR_POP 33
24 LOAD_FAST 1 (opg)
27 LOAD_CONST 2 (129)
30 COMPARE_OP 2 (==)
>> 33 POP_TOP
34 LOAD_CONST 0 (None)
37 RETURN_VALUE
Как отмечает Hoopdady, вы также неправильно разбиваете свою строку. line.split()
или же line.split(None)
будет разделен на последовательные пробелы.