Python tương đương với && (logic-và) trong câu lệnh if?

Tôi đang gặp lỗi trong điều kiện IF. Tôi đang làm gì sai?

Có một lý do mà bạn nhận được SyntaxErrorlà không có &&toán tử nào trong Python. Tương tự như vậy ||không phải! là toán tử Python hợp lệ .

Một số toán tử bạn có thể biết từ các ngôn ngữ khác có tên khác trong Python. Các toán tử logic &&||thực sự được gọi andor. Tương tự như vậy, toán tử phủ định logic !được gọi not.

Vì vậy, bạn chỉ có thể viết:

if

len

(

a

)

%

2

==

0

and

len

(

b

)

%

2

==

0

:

hoặc thậm chí:

if

not

(

len

(

a

)

%

2

or

len

(

b

)

%

2

):

Một số thông tin bổ sung (có thể có ích):

Tôi đã tóm tắt toán tử “tương đương” trong bảng này:

+------------------------------+---------------------+ | Operator (other languages) | Operator (Python) | +==============================+=====================+ | && | and | +------------------------------+---------------------+ | || | or | +------------------------------+---------------------+ | ! | not | +------------------------------+---------------------+

Xem thêm tài liệu Python: 6.11. Hoạt động Boolean .

Bên cạnh các toán tử logic, Python cũng có các toán tử bitwise / binary:

+--------------------+--------------------+ | Logical operator | Bitwise operator | +====================+====================+ | and | & | +--------------------+--------------------+ | or | | | +--------------------+--------------------+

Không có phủ định bitwise trong Python (chỉ là toán tử nghịch đảo bitwise ~– nhưng điều đó không tương đương với not).

Xem thêm 6.6. Số học đơn phương và các phép toán bitwise / nhị phân và 6.7. Phép toán số học nhị phân .

Các toán tử logic (như trong nhiều ngôn ngữ khác) có lợi thế là chúng được ngắn mạch. Điều đó có nghĩa là nếu toán hạng thứ nhất đã xác định kết quả, thì toán tử thứ hai hoàn toàn không được đánh giá.

Để hiển thị điều này, tôi sử dụng một hàm chỉ đơn giản là lấy một giá trị, in nó và trả lại nó. Điều này rất hữu ích để xem những gì thực sự được đánh giá vì các báo cáo in:

>>>

def

print_and_return

(

value

):

...

print

(

value

)

...

return

value

>>>

res

=

print_and_return

(

False

)

and

print_and_return

(

True

)

False

Như bạn có thể thấy chỉ có một câu lệnh in được thực thi, do đó Python thực sự thậm chí không nhìn vào toán hạng đúng.

Đây không phải là trường hợp cho các toán tử nhị phân. Những người luôn đánh giá cả hai toán hạng:

>>>

res

=

print_and_return

(

False

)

&

print_and_return

(

True

);

False

True

Nhưng nếu toán hạng thứ nhất không đủ thì dĩ nhiên, toán tử thứ hai được ước tính:

>>>

res

=

print_and_return

(

True

)

and

print_and_return

(

False

);

True

False

Để tóm tắt đây là một Bảng khác:

+-----------------+-------------------------+ | Expression | Right side evaluated? | +=================+=========================+ | `True` and ... | Yes | +-----------------+-------------------------+ | `False` and ... | No | +-----------------+-------------------------+ | `True` or ... | No | +-----------------+-------------------------+ | `False` or ... | Yes | +-----------------+-------------------------+

Các TrueFalseđại diện cho những gì bool(left-hand-side)trở lại, họ không phải là Truehay False, họ chỉ cần phải trả lại Truehoặc Falsekhi boolđược gọi vào chúng (1).

Vì vậy, trong Mã giả (!), andVà các orhàm hoạt động như sau:

def and(expr1, expr2): left = evaluate(expr1) if bool(left): return evaluate(expr2) else: return left def or(expr1, expr2): left = evaluate(expr1) if bool(left): return left else: return evaluate(expr2)

Lưu ý rằng đây là mã giả chứ không phải mã Python. Trong Python bạn không thể tạo các hàm được gọi andhoặc orvì đây là các từ khóa. Ngoài ra, bạn không bao giờ nên sử dụng “đánh giá” hoặc if bool(...).

Tùy chỉnh hành vi của các lớp của riêng bạn

Tiềm ẩn này boolcuộc gọi có thể được sử dụng để tùy chỉnh cách lớp học của bạn cư xử với and, ornot.

Để chỉ ra làm thế nào điều này có thể được tùy chỉnh, tôi sử dụng lớp này một lần nữa printđể theo dõi những gì đang xảy ra:

class

Test

(

object

):

def

__init__

(

self

,

value

):

self

.

value

=

value

def

__bool__

(

self

):

print

(

'__bool__ called on {!r}'

.

format

(

self

))

return

bool

(

self

.

value

)

__nonzero__

=

__bool__

# Python 2 compatibility

def

__repr__

(

self

):

return

"{self.__class__.__name__}({self.value})"

.

format

(

self

=

self

)

Vì vậy, hãy xem điều gì xảy ra với lớp đó kết hợp với các toán tử này:

>>>

if

Test

(

True

)

and

Test

(

False

):

...

pass

__bool__ called on

Test

(

True

)

__bool__ called on

Test

(

False

)

>>>

if

Test

(

False

)

or

Test

(

False

):

...

pass

__bool__ called on

Test

(

False

)

__bool__ called on

Test

(

False

)

>>>

if

not

Test

(

True

):

...

pass

__bool__ called on

Test

(

True

)

Nếu bạn không có __bool__phương thức thì Python cũng kiểm tra xem đối tượng có __len__phương thức không và liệu nó có trả về giá trị lớn hơn không. Điều đó có thể hữu ích để biết trong trường hợp bạn tạo một thùng chứa trình tự.

Xem thêm 4.1. Kiểm tra giá trị thật .

Mảng NumPy và các lớp con

Có thể vượt quá phạm vi của câu hỏi ban đầu nhưng trong trường hợp bạn đang xử lý các mảng hoặc lớp con NumPy (như Pandas Series hoặc DataFrames) thì boolcuộc gọi ngầm sẽ gây ra sự sợ hãi ValueError:

>>>

import

numpy

as

np

>>>

arr

=

np

.

array

([

1

,

2

,

3

])

>>>

bool

(

arr

)

ValueError

:

The

truth value of an array

with

more than one element

is

ambiguous

.

Use

a

.

any

()

or

a

.

all

()

>>>

arr

and

arr

ValueError

:

The

truth value of an array

with

more than one element

is

ambiguous

.

Use

a

.

any

()

or

a

.

all

()

>>>

import

pandas

as

pd

>>>

s

=

pd

.

Series

([

1

,

2

,

3

])

>>>

bool

(

s

)

ValueError

:

The

truth value of a

Series

is

ambiguous

.

Use

a

.

empty

,

a

.

bool

(),

a

.

item

(),

a

.

any

()

or

a

.

all

().

>>>

s

and

s

ValueError

:

The

truth value of a

Series

is

ambiguous

.

Use

a

.

empty

,

a

.

bool

(),

a

.

item

(),

a

.

any

()

or

a

.

all

().

Trong những trường hợp này, bạn có thể sử dụng logic và hàm từ NumPy để thực hiện phần tử khôn ngoan and(hoặc or):

>>>

np

.

logical_and

(

np

.

array

([

False

,

False

,

True

,

True

]),

np

.

array

([

True

,

False

,

True

,

False

]))

array

([

False

,

False

,

True

,

False

])

>>>

np

.

logical_or

(

np

.

array

([

False

,

False

,

True

,

True

]),

np

.

array

([

True

,

False

,

True

,

False

]))

array

([

True

,

False

,

True

,

True

])

Nếu bạn đang xử lý chỉ với các mảng boolean, bạn cũng có thể sử dụng các toán tử nhị phân với NumPy, chúng thực hiện các phép so sánh phần tử (nhưng cũng là nhị phân):

>>>

np

.

array

([

False

,

False

,

True

,

True

])

&

np

.

array

([

True

,

False

,

True

,

False

])

array

([

False

,

False

,

True

,

False

])

>>>

np

.

array

([

False

,

False

,

True

,

True

])

|

np

.

array

([

True

,

False

,

True

,

False

])

array

([

True

,

False

,

True

,

True

])

(1)

Cuộc boolgọi trên toán hạng phải trả về Truehoặc Falsekhông hoàn toàn chính xác. Đây chỉ là toán hạng đầu tiên cần trả về boolean trong __bool__phương thức của nó :

class

Test

(

object

):

def

__init__

(

self

,

value

):

self

.

value

=

value

def

__bool__

(

self

):

return

self

.

value __nonzero__

=

__bool__

# Python 2 compatibility

def

__repr__

(

self

):

return

"{self.__class__.__name__}({self.value})"

.

format

(

self

=

self

)

>>>

x

=

Test

(

10

)

and

Test

(

10

)

TypeError

:

__bool__ should

return

bool

,

returned int

>>>

x1

=

Test

(

True

)

and

Test

(

10

)

>>>

x2

=

Test

(

False

)

and

Test

(

10

)

Đó là bởi vì andthực sự trả về toán hạng đầu tiên nếu toán hạng thứ nhất ước lượng Falsevà nếu nó ước lượng Truethì nó trả về toán hạng thứ hai:

>>>

x1

Test

(

10

)

>>>

x2

Test

(

False

)

Tương tự cho ornhưng chỉ là cách khác:

>>>

Test

(

True

)

or

Test

(

10

)

Test

(

True

)

>>>

Test

(

False

)

or

Test

(

10

)

Test

(

10

)

Tuy nhiên, nếu bạn sử dụng chúng trong một iftuyên bố, ifnó cũng sẽ ngầm gọi boolkết quả. Vì vậy, những điểm tốt hơn có thể không phù hợp với bạn.