Làm thế nào để kiểm tra nhiều biến với một giá trị?
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
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:
x
và y
được đánh giá theo cách khác của riêng chúng ( False
nếu 0
, True
nế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 ( in
mấ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 == 1
sẽ được kiểm tra.
Điều này là do sự ưu tiên của toán tử . Các or
nhà 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 == 1
thự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 z
sẽ đá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 z
sẽ 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 == 1
sẽ là False
, mặc dù y == 1
sẽ 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 3
sẽ thất bại vì những lý do tương tự. Sử dụng x == 1 or x == 2 or x == 3
hoặc x in {1, 2, 3}
.
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]]
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à True
hay 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])
Cách viết trực tiếp x or y or z == 0
là
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 if
s 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
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])
Để 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 itertools
và operator
.
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 map
hà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)
vì operator
là 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 lambda
phả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))
Đặ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}
là {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).
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 rot
tồ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.
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
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)
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]
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;
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']
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)]
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
and
là tổng bình phương của các phương trình - logic
or
là 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.
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")
Nó có thể được thực hiện dễ dàng như
for value in [var1,var2,var3]:
li.append("targetValue")
Để 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}:
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])
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']
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
Đ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);
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']
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 :-(