Làm thế nào để kiểm tra nhiều biến với một giá trị?

Feb 27 2013

Tôi đang cố gắng tạo một hàm sẽ so sánh nhiều biến với một số nguyên và xuất ra một chuỗi gồm ba chữ cái. Tôi đã tự hỏi liệu có cách nào để dịch điều này sang Python không. Vì vậy, hãy nói:

x = 0
y = 1
z = 3
mylist = []

if x or y or z == 0 :
    mylist.append("c")
if x or y or z == 1 :
    mylist.append("d")
if x or y or z == 2 :
    mylist.append("e")
if x or y or z == 3 : 
    mylist.append("f")

mà sẽ trả về một danh sách:

["c", "d", "f"]

Có phải bất cư thứ gì như thế này đều được?

Trả lời

912 MartijnPieters Feb 27 2013 at 19:27

Bạn hiểu sai cách hoạt động của các biểu thức boolean; chúng không hoạt động giống như một câu tiếng Anh và đoán rằng bạn đang nói về cùng một so sánh cho tất cả các tên ở đây. Bạn đang tìm kiếm:

if x == 1 or y == 1 or z == 1:

xyđược đánh giá theo cách khác của riêng chúng ( Falsenếu 0, Truenếu không).

Bạn có thể rút ngắn điều đó bằng cách sử dụng thử nghiệm ngăn chặn đối với một tuple :

if 1 in (x, y, z):

hoặc tốt hơn vẫn là:

if 1 in {x, y, z}:

bằng cách sử dụng aset để tận dụng lợi thế của kiểm tra thành viên chi phí không đổi ( inmất một khoảng thời gian cố định bất kể toán hạng bên trái là gì).

Khi bạn sử dụng or, python sẽ coi mỗi bên của toán tử là các biểu thức riêng biệt . Trước tiên, biểu thức x or y == 1được coi như một phép thử boolean x, sau đó nếu sai, biểu thức y == 1sẽ được kiểm tra.

Điều này là do sự ưu tiên của toán tử . Các ornhà khai thác có độ ưu tiên thấp hơn so với ==thử nghiệm, vì vậy sau này được đánh giá đầu tiên .

Tuy nhiên, ngay cả khi trường hợp này không xảy ra và thay vào đó, biểu thức x or y or z == 1thực sự được giải thích (x or y or z) == 1, điều này vẫn sẽ không làm được những gì bạn mong đợi.

x or y or zsẽ đánh giá đối số đầu tiên là 'true', ví dụ không phải False, số 0 hoặc trống (xem biểu thức boolean để biết chi tiết về những gì Python coi là sai trong ngữ cảnh boolean).

Vì vậy, đối với các giá trị x = 2; y = 1; z = 0, x or y or zsẽ giải quyết thành 2, bởi vì đó là giá trị giống như true đầu tiên trong các đối số. Sau đó 2 == 1sẽ là False, mặc dù y == 1sẽ là True.

Điều tương tự sẽ áp dụng cho nghịch đảo; thử nghiệm nhiều giá trị với một biến duy nhất; x == 1 or 2 or 3sẽ thất bại vì những lý do tương tự. Sử dụng x == 1 or x == 2 or x == 3hoặc x in {1, 2, 3}.

96 dansalmo Jul 12 2013 at 04:56

Vấn đề của bạn được giải quyết dễ dàng hơn với cấu trúc từ điển như:

x = 0
y = 1
z = 3
d = {0: 'c', 1:'d', 2:'e', 3:'f'}
mylist = [d[k] for k in [x, y, z]]
67 ThatGuyRussell Aug 19 2015 at 09:34

Như đã nói bởi Martijn Pieters, định dạng đúng và nhanh nhất là:

if 1 in {x, y, z}:

Sử dụng lời khuyên của anh ấy, bây giờ bạn sẽ có các câu lệnh if riêng biệt để Python sẽ đọc từng câu lệnh cho dù câu lệnh trước là Truehay False. Nhu la:

if 0 in {x, y, z}:
    mylist.append("c")
if 1 in {x, y, z}:
    mylist.append("d")
if 2 in {x, y, z}:
    mylist.append("e")
...

Điều này sẽ hiệu quả, nhưng nếu bạn cảm thấy thoải mái khi sử dụng từ điển (xem những gì tôi đã làm ở đó), bạn có thể làm sạch điều này bằng cách tạo một từ điển ban đầu ánh xạ các số thành các chữ cái bạn muốn, sau đó chỉ cần sử dụng vòng lặp for:

num_to_letters = {0: "c", 1: "d", 2: "e", 3: "f"}
for number in num_to_letters:
    if number in {x, y, z}:
        mylist.append(num_to_letters[number])
46 akaRem Jul 12 2013 at 04:16

Cách viết trực tiếp x or y or z == 0

if any(map((lambda value: value == 0), (x,y,z))):
    pass # write your logic.

Nhưng tôi không nghĩ, bạn thích nó. :) Và cách này là xấu xí.

Cách khác (tốt hơn) là:

0 in (x, y, z)

BTW rất nhiều ifs có thể được viết như thế này

my_cases = {
    0: Mylist.append("c"),
    1: Mylist.append("d")
    # ..
}

for key in my_cases:
    if key in (x,y,z):
        my_cases[key]()
        break
35 ytpillai May 25 2015 at 10:53

Nếu bạn rất lười biếng, bạn có thể đặt các giá trị bên trong một mảng. Nhu la

list = []
list.append(x)
list.append(y)
list.append(z)
nums = [add numbers here]
letters = [add corresponding letters here]
for index in range(len(nums)):
    for obj in list:
        if obj == num[index]:
            MyList.append(letters[index])
            break

Bạn cũng có thể đưa các số và chữ cái vào từ điển và thực hiện nó, nhưng điều này có lẽ phức tạp hơn rất nhiều so với câu lệnh if đơn giản. Đó là những gì bạn nhận được khi cố gắng trở nên lười biếng hơn nữa :)

Một điều nữa, của bạn

if x or y or z == 0:

sẽ biên dịch, nhưng không theo cách bạn muốn. Khi bạn chỉ cần đặt một biến trong câu lệnh if (ví dụ)

if b

chương trình sẽ kiểm tra xem biến không phải là null hay không. Một cách khác để viết câu lệnh trên (có ý nghĩa hơn) là

if bool(b)

Bool là một hàm có sẵn trong python về cơ bản thực hiện lệnh xác minh câu lệnh boolean (Nếu bạn không biết đó là gì, thì đó là những gì bạn đang cố gắng thực hiện trong câu lệnh if của mình ngay bây giờ :))

Một cách lười biếng khác mà tôi tìm thấy là:

if any([x==0, y==0, z==0])
33 GuiltyDolphin Jun 05 2014 at 00:09

Để kiểm tra xem một giá trị có được chứa trong một tập hợp các biến hay không, bạn có thể sử dụng các mô-đun có sẵn itertoolsoperator.

Ví dụ:

Nhập khẩu:

from itertools import repeat
from operator import contains

Khai báo các biến:

x = 0
y = 1
z = 3

Tạo ánh xạ các giá trị (theo thứ tự bạn muốn kiểm tra):

check_values = (0, 1, 3)

Sử dụng itertoolsđể cho phép lặp lại các biến:

check_vars = repeat((x, y, z))

Cuối cùng, sử dụng maphàm để tạo một trình lặp:

checker = map(contains, check_vars, check_values)

Sau đó, khi kiểm tra các giá trị (theo thứ tự ban đầu), hãy sử dụng next():

if next(checker)  # Checks for 0
    # Do something
    pass
elif next(checker)  # Checks for 1
    # Do something
    pass

Vân vân...

Điều này có lợi thế hơn lambda x: x in (variables)operatorlà mô-đun có sẵn và nhanh hơn và hiệu quả hơn so với việc sử dụng mô-đun lambdaphải tạo một chức năng tại chỗ tùy chỉnh.

Một tùy chọn khác để kiểm tra xem có giá trị khác 0 (hoặc Sai) trong danh sách hay không:

not (x and y and z)

Tương đương:

not all((x, y, z))
31 B.M. Jun 10 2015 at 03:46

Đặt là cách tiếp cận tốt ở đây, vì nó sắp xếp thứ tự các biến, điều dường như là mục tiêu của bạn ở đây. {z,y,x}{0,1,3}bất kỳ thứ tự của các tham số.

>>> ["cdef"[i] for i in {z,x,y}]
['c', 'd', 'f']

Theo cách này, toàn bộ lời giải là O (n).

31 RolfofSaxony Sep 10 2016 at 22:44

Tất cả các câu trả lời tuyệt vời được cung cấp ở đây tập trung vào yêu cầu cụ thể của áp phích gốc và tập trung vào if 1 in {x,y,z}giải pháp do Martijn Pieters đưa ra.
Điều họ bỏ qua là hàm ý rộng hơn của câu hỏi:
Làm cách nào để kiểm tra một biến so với nhiều giá trị?
Giải pháp được cung cấp sẽ không hoạt động đối với các lần truy cập một phần nếu sử dụng chuỗi, ví dụ:
Kiểm tra xem chuỗi "Wild" có nhiều giá trị không

>>> x = "Wild things"
>>> y = "throttle it back"
>>> z = "in the beginning"
>>> if "Wild" in {x, y, z}: print (True)
... 

hoặc là

>>> x = "Wild things"
>>> y = "throttle it back"
>>> z = "in the beginning"
>>> if "Wild" in [x, y, z]: print (True)
... 

đối với trường hợp này, dễ dàng nhất để chuyển đổi thành một chuỗi

>>> [x, y, z]
['Wild things', 'throttle it back', 'in the beginning']
>>> {x, y, z}
{'in the beginning', 'throttle it back', 'Wild things'}
>>> 

>>> if "Wild" in str([x, y, z]): print (True)
... 
True
>>> if "Wild" in str({x, y, z}): print (True)
... 
True

Tuy nhiên, cần lưu ý rằng, như đã đề cập bởi @codeforester, các giới hạn từ bị mất với phương pháp này, như trong:

>>> x=['Wild things', 'throttle it back', 'in the beginning']
>>> if "rot" in str(x): print(True)
... 
True

3 chữ cái rottồn tại kết hợp trong danh sách nhưng không phải là một từ riêng lẻ. Kiểm tra "thối" sẽ không thành công nhưng nếu một trong các mục trong danh sách là "thối trong địa ngục", điều đó cũng sẽ thất bại.
Kết quả là, hãy cẩn thận với tiêu chí tìm kiếm của bạn nếu sử dụng phương pháp này và lưu ý rằng nó có giới hạn này.

30 BhargavBoda Jan 13 2015 at 19:10

Tôi nghĩ điều này sẽ xử lý nó tốt hơn:

my_dict = {0: "c", 1: "d", 2: "e", 3: "f"}

def validate(x, y, z):
    for ele in [x, y, z]:
        if ele in my_dict.keys():
            return my_dict[ele]

Đầu ra:

print validate(0, 8, 9)
c
print validate(9, 8, 9)
None
print validate(9, 8, 2)
e
30 hamid Apr 10 2015 at 10:29

Nếu bạn muốn sử dụng các câu lệnh if, else sau đây là một giải pháp khác:

myList = []
aList = [0, 1, 3]

for l in aList:
    if l==0: myList.append('c')
    elif l==1: myList.append('d')
    elif l==2: myList.append('e')
    elif l==3: myList.append('f')

print(myList)
26 SakshamVarma Feb 27 2015 at 08:31
d = {0:'c', 1:'d', 2:'e', 3: 'f'}
x, y, z = (0, 1, 3)
print [v for (k,v) in d.items() if x==k or y==k or z==k]
26 michaelzxc858 Jun 29 2015 at 14:03

Mã này có thể hữu ích

L ={x, y, z}
T= ((0,"c"),(1,"d"),(2,"e"),(3,"f"),)
List2=[]
for t in T :
if t[0] in L :
    List2.append(t[1])
    break;
12 SiddharthSatpathy Dec 03 2018 at 12:13

Bạn có thể thử phương pháp hiển thị bên dưới. Trong phương pháp này, bạn sẽ có quyền tự do chỉ định / nhập số lượng biến mà bạn muốn nhập.

mydict = {0:"c", 1:"d", 2:"e", 3:"f"}
mylist= []

num_var = int(raw_input("How many variables? ")) #Enter 3 when asked for input.

for i in range(num_var): 
    ''' Enter 0 as first input, 1 as second input and 3 as third input.'''
    globals()['var'+str('i').zfill(3)] = int(raw_input("Enter an integer between 0 and 3 "))
    mylist += mydict[globals()['var'+str('i').zfill(3)]]

print mylist
>>> ['c', 'd', 'f']
10 VinayakKaniyarakkal Jun 05 2017 at 13:50

Giải pháp một dòng:

mylist = [{0: 'c', 1: 'd', 2: 'e', 3: 'f'}[i] for i in [0, 1, 2, 3] if i in (x, y, z)]

Hoặc là:

mylist = ['cdef'[i] for i in range(4) if i in (x, y, z)]
9 Sergei Feb 18 2019 at 00:55

Có thể bạn cần công thức trực tiếp cho bộ bit đầu ra.

x=0 or y=0 or z=0   is equivalent to x*y*z = 0

x=1 or y=1 or z=1   is equivalent to (x-1)*(y-1)*(z-1)=0

x=2 or y=2 or z=2   is equivalent to (x-2)*(y-2)*(z-2)=0

Hãy ánh xạ tới các bit: 'c':1 'd':0xb10 'e':0xb100 'f':0xb1000

Quan hệ của isc (là 'c'):

if xyz=0 then isc=1 else isc=0

Sử dụng công thức toán học if https://youtu.be/KAdKCgBGK0k?list=PLnI9xbPdZUAmUL8htSl6vToPQRRN3hhFp&t=315

[c]: (xyz=0 and isc=1) or (((xyz=0 and isc=1) or (isc=0)) and (isc=0))

[d]: ((x-1)(y-1)(z-1)=0 and isc=2) or (((xyz=0 and isd=2) or (isc=0)) and (isc=0))

...

Kết nối các công thức này bằng logic sau:

  • logic andlà tổng bình phương của các phương trình
  • logic orlà sản phẩm của các phương trình

và bạn sẽ có một phương trình tổng thể hiện tổng và bạn có tổng công thức của tổng

thì tổng & 1 là c, tổng & 2 là d, tổng & 4 là e, tổng & 5 là f

Sau đó, bạn có thể tạo mảng được xác định trước trong đó chỉ mục của các phần tử chuỗi sẽ tương ứng với chuỗi sẵn sàng.

array[sum] cung cấp cho bạn chuỗi.

8 rsalmei Aug 06 2018 at 13:26

Cách khó hiểu nhất để biểu diễn mã giả của bạn bằng Python sẽ là:

x = 0
y = 1
z = 3
mylist = []

if any(v == 0 for v in (x, y, z)):
    mylist.append("c")
if any(v == 1 for v in (x, y, z)):
    mylist.append("d")
if any(v == 2 for v in (x, y, z)):
    mylist.append("e")
if any(v == 3 for v in (x, y, z)):
    mylist.append("f")
7 Seenivasan Nov 06 2018 at 21:26

Nó có thể được thực hiện dễ dàng như

for value in [var1,var2,var3]:
     li.append("targetValue")
5 alamin Sep 20 2018 at 09:18

Để kiểm tra nhiều biến với một giá trị duy nhất: if 1 in {a,b,c}:

Để kiểm tra nhiều giá trị với một biến: if a in {1, 2, 3}:

4 firelynx Aug 27 2018 at 16:45

Có vẻ như bạn đang xây dựng một loại mật mã Caesar.

Một cách tiếp cận tổng quát hơn là:

input_values = (0, 1, 3)
origo = ord('c')
[chr(val + origo) for val in inputs]

đầu ra

['c', 'd', 'f']

Không chắc đó có phải là tác dụng phụ mong muốn của mã của bạn hay không, nhưng thứ tự đầu ra của bạn sẽ luôn được sắp xếp.

Nếu đây là những gì bạn muốn, dòng cuối cùng có thể được thay đổi thành:

sorted([chr(val + origo) for val in inputs])
3 Massifox Oct 11 2019 at 19:17

Nếu không có dict, hãy thử giải pháp này:

x, y, z = 0, 1, 3    
offset = ord('c')
[chr(i + offset) for i in (x,y,z)]

và cho:

['c', 'd', 'f']
2 RohitGawas Jul 31 2018 at 23:54

Bạn có thể sử dụng từ điển:

x = 0
y = 1
z = 3
list=[]
dict = {0: 'c', 1: 'd', 2: 'e', 3: 'f'}
if x in dict:
    list.append(dict[x])
else:
    pass

if y in dict:
    list.append(dict[y])
else:
    pass
if z in dict:
    list.append(dict[z])
else:
    pass

print list
Mayur Apr 06 2019 at 05:03

Điều này sẽ giúp bạn.

def test_fun(val):
    x = 0
    y = 1
    z = 2
    myList = []
    if val in (x, y, z) and val == 0:
        myList.append("C")
    if val in (x, y, z) and val == 1:
        myList.append("D")
    if val in (x, y, z) and val == 2:
        myList.append("E")

test_fun(2);
Serhii Sep 10 2019 at 01:23

Bạn có thể hợp nhất điều này

x = 0
y = 1
z = 3

trong một biến.

In [1]: xyz = (0,1,3,) 
In [2]: mylist = []

Thay đổi các điều kiện của chúng tôi như:

In [3]: if 0 in xyz: 
    ...:     mylist.append("c") 
    ...: if 1 in xyz: 
    ...:     mylist.append("d") 
    ...: if 2 in xyz: 
    ...:     mylist.append("e") 
    ...: if 3 in xyz:  
    ...:     mylist.append("f") 

Đầu ra:

In [21]: mylist                                                                                
Out[21]: ['c', 'd', 'f']
fhgd Nov 06 2019 at 18:11

Vấn đề

Trong khi mẫu để kiểm tra nhiều giá trị

>>> 2 in {1, 2, 3}
True
>>> 5 in {1, 2, 3}
False

rất dễ đọc và đang hoạt động trong nhiều tình huống, có một cạm bẫy:

>>> 0 in {True, False}
True

Nhưng chúng tôi muốn có

>>> (0 is True) or (0 is False)
False

Giải pháp

Một tổng quát của biểu thức trước dựa trên câu trả lời từ ytpillai :

>>> any([0 is True, 0 is False])
False

có thể được viết là

>>> any(0 is item for item in (True, False))
False

Mặc dù biểu thức này trả về kết quả phù hợp nhưng nó không thể đọc được như biểu thức đầu tiên :-(