I'm trying to make a function that will compare multiple variables to an integer and output a string of three letters. I was wondering if there was a way to translate this into Python. So say:
我正在尝试创建一个函数,它将多个变量与一个整数进行比较,并输出一个由三个字母组成的字符串。我想知道是否有办法将它转换成Python。所以说:
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")
which would return a list of
哪个会返回一个列表
["c", "d", "f"]
Is something like this possible?
这样的事情可能吗?
13 个解决方案
#1
522
You misunderstand how boolean expressions work; they don't work like an English sentence and guess that you are talking about the same comparison for all names here. You are looking for:
你误解了布尔表达式的工作原理;它们不像英文句子,而且猜你在这里谈论的是所有名字的相同比较。你正在寻找:
if x == 1 or y == 1 or z == 1:
x
and y
are otherwise evaluated on their own (False
if 0
, True
otherwise).
x和y单独计算(如果为0,则为False,否则为True)。
You can shorten that using a containment test against a tuple:
您可以对一个元组使用包含测试来缩短这个时间:
if 1 in (x, y, z):
or better still:
或者更好的是:
if 1 in {x, y, z}:
using a set
to take advantage of the constant-cost membership test (in
takes a fixed amount of time whatever the left-hand operand is).
使用一个集合来利用成本不变的成员关系测试(无论左手操作数是什么,in都需要固定的时间)。
When you use or
, python sees each side of the operator as separate expressions. The expression x or y == 1
is treated as first a boolean test for x
, then if that is False, the expression y == 1
is tested.
当您使用or时,python将操作符的每一面视为独立的表达式。表达式x或y == 1被视为对x的第一个布尔测试,如果这是错误的,那么表达式y == 1将被测试。
This is due to operator precedence. The or
operator has a lower precedence than the ==
test, so the latter is evaluated first.
这是由于操作符的优先级。or操作符的优先级比=测试低,因此首先计算后者。
However, even if this were not the case, and the expression x or y or z == 1
was actually interpreted as (x or y or z) == 1
instead, this would still not do what you expect it to do.
然而,即使不是这样,表达式x或y或z == 1实际上被解释为(x或y或z) = 1,这仍然不能实现预期的效果。
x or y or z
would evaluate to the first argument that is 'truthy', e.g. not False
, numeric 0 or empty (see boolean expressions for details on what Python considers false in a boolean context).
x或y或z将评估第一个参数是“truthy”,例如not False、numeric 0或empty(请参阅布尔表达式,以了解在布尔上下文中Python认为False的细节)。
So for the values x = 2; y = 1; z = 0
, x or y or z
would resolve to 2
, because that is the first true-like value in the arguments. Then 2 == 1
would be False
, even though y == 1
would be True
.
对于x = 2;y = 1;z = 0 x或y或z会分解为2,因为这是参数中的第一个真实值。然后2 == 1是假的,即使y = 1是真的。
The same would apply to the inverse; testing multiple values against a single variable; x == 1 or 2 or 3
would fail for the same reasons. Use x == 1 or x == 2 or x == 3
or x in {1, 2, 3}
.
反过来也一样;对单个变量测试多个值;x == 1或2或3会因为同样的原因而失败。使用x == 1或x = 2或x = 3或{1,2,3}中的x。
#2
47
Your problem is more easily addressed with a dictionary structure like:
你的问题更容易通过字典结构来解决,比如:
x = 0
y = 1
z = 3
d = {0: 'c', 1:'d', 2:'e', 3:'f'}
mylist = [d[k] for k in [x, y, z]]
#3
28
Previous Solution: As stated by Martijn Pieters, the correct, and fastest, format is:
先前的解决方案:正如Martijn Pieters所说,正确且最快的格式是:
if 1 in {x, y, z}:
The one major issue that does not seem to be addressed is that you want your output list to include each letter after a true if statement.
Using only Martijn Pieters' advice you would now have:
似乎没有解决的一个主要问题是,您希望您的输出列表在一个真实的if语句之后包含每个字母。只使用Martijn Pieters现在的建议:
if 0 in {x, y, z}:
Mylist.append("c")
elif 1 in {x, y, z}:
Mylist.append("d")
...
Problem: The first if statement would return true, and you would never get to the following elif statement. So your list would simply return:
问题:第一个if语句将返回true,您永远不会得到下面的elif语句。所以你的列表只会返回:
["c"]
What you want is to have separate if statements so that python will read each statement whether the former were true or false. Such as:
您需要的是有独立的if语句,以便python能够读取每个语句,无论前者是真还是假。如:
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")
...
This will work, but 'if' you are comfortable using dictionaries (see what I did there), you can clean this up by making an initial dictionary mapping the numbers to the letters you want, then just using a 'for' loop:
这是可行的,但是“如果”你喜欢使用字典(看看我在那里做了什么),你可以制作一个初始字典,将数字映射到你想要的字母,然后使用“for”循环:
numToLetters = {0:"c", 1:"d", 2:"e", 3:"f"}
for number in numToLetters:
if number in {x, y, z}:
Mylist.append(numToLetters[number])
#4
18
The direct way to write x or y or z == 0
is
直接写x或y或z == 0的方法。
if any(map((lambda value: value == 0), (x,y,z))):
pass # write your logic.
But I dont think, you like it. :) And this way is ugly.
但我不认为你喜欢它。这条路很难看。
The other way (a better) is:
另一个更好的方法是:
0 in (x, y, z)
BTW lots of if
s could be written as something like this
顺便说一句,很多if都可以写成这样
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
#5
15
If you ARE very very lazy, you can put the values inside an array. Such as
如果您非常非常懒,您可以将值放入一个数组中。如
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
You can also put the numbers and letters in a dictionary and do it, but this is probably a LOT more complicated than simply if statements. That's what you get for trying to be extra lazy :)
你也可以把数字和字母放到字典里去做,但是这可能比简单的if语句要复杂得多。这就是你试图变得特别懒惰的原因:
One more thing, your
一件事,你的
if x or y or z == 0:
will compile, but not in the way you want it to. When you simply put a variable in an if statement (example)
会编译,但不会按你想要的方式进行编译。当你在if语句中放入一个变量时(例如)
if b
the program will check if the variable is not null. Another way to write the above statement (which makes more sense) is
程序将检查变量是否为空。另一种写法(更有意义)是
if bool(b)
Bool is an inbuilt function in python which basically does the command of verifying a boolean statement (If you don't know what that is, it is what you are trying to make in your if statement right now :))
Bool是python中的一个内置函数,它基本上执行验证布尔语句的命令(如果您不知道它是什么,那么它就是您现在在If语句中要做的:)
Another lazy way I found is :
我发现的另一种懒惰的方式是:
if any([x==0, y==0, z==0])
#6
12
To check if a value is contained within a set of variables you can use the inbuilt modules itertools
and operator
.
要检查一个值是否包含在一组变量中,可以使用内置的模块itertools和操作符。
For example:
例如:
Imports:
进口:
from itertools import repeat
from operator import contains
Declare variables:
声明变量:
x = 0
y = 1
z = 3
Create mapping of values (in the order you want to check):
创建值的映射(按照您想要检查的顺序):
check_values = (0, 1, 3)
Use itertools
to allow repetition of the variables:
使用迭代工具允许重复变量:
check_vars = repeat((x, y, z))
Finally, use the map
function to create an iterator:
最后,使用map函数创建一个迭代器:
checker = map(contains, check_vars, check_values)
Then, when checking for the values (in the original order), use next()
:
然后,在检查值(按原始顺序)时,使用next():
if next(checker) # Checks for 0
# Do something
pass
elif next(checker) # Checks for 1
# Do something
pass
etc...
等等……
This has an advantage over the lambda x: x in (variables)
because operator
is an inbuilt module and is faster and more efficient than using lambda
which has to create a custom in-place function.
这比(变量)中的x: x有一个优点,因为操作符是一个内置模块,比使用lambda更快、更高效,lambda必须创建自定义的就地函数。
Another option for checking if there is a non-zero (or False) value in a list:
检查列表中是否有非零(或假)值的另一个选项:
not (x and y and z)
Equivalent:
相当于:
not all((x, y, z))
#7
12
Set is the good approach here, because it orders the variables, what seems to be your goal here. {z,y,x}
is {0,1,3}
whatever the order of the parameters.
Set是一个很好的方法,因为它对变量进行排序,这是你的目标。z,y,x}是{0,1,3}不管参数的顺序是什么。
>>> ["cdef"[i] for i in {z,x,y}]
['c', 'd', 'f']
This way, the whole solution is O(n).
这样,整个解就是O(n)
#8
11
I think this will handle it better:
我认为这样会更好:
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]
Output:
输出:
print validate(0, 8, 9)
c
print validate(9, 8, 9)
None
print validate(9, 8, 2)
e
#9
11
This code may be helpful
这段代码可能会有帮助
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;
#10
11
If you want to use if, else statements following is another solution:
如果你想使用If,下面的else语句是另一个解决方案:
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)
#11
10
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]
#12
10
All of the excellent answers provided here concentrate on the specific requirement of the original poster and concentrate on the if 1 in {x,y,z}
solution put forward by Martijn Pieters.
What they ignore is the broader implication of the question:
How do I test one variable against multiple values?
The solution provided will not work for partial hits if using strings for example:
Test if the string "Wild" is in multiple values
这里提供的所有优秀答案都集中在原始海报的具体要求上,集中在Martijn Pieters提出的{x,y,z}解决方案中的if 1。他们忽略了一个更广泛的问题:如何针对多个值测试一个变量?如果使用字符串(例如:测试字符串“Wild”是否在多个值中),所提供的解决方案将不能用于部分命中
>>> x="Wild things"
>>> y="throttle it back"
>>> z="in the beginning"
>>> if "Wild" in {x,y,z}: print (True)
...
or
或
>>> x="Wild things"
>>> y="throttle it back"
>>> z="in the beginning"
>>> if "Wild" in [x,y,z]: print (True)
...
for this scenario it's easiest to convert to a string
对于这个场景,最容易转换为字符串。
>>> [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
It should be noted however, as mentioned by @codeforester
, that word boundries are lost with this method, as in:
但是需要指出的是,正如@codeforester提到的,这种方法会丢失单词boundries,如:
>>> x=['Wild things', 'throttle it back', 'in the beginning']
>>> if "rot" in str(x): print(True)
...
True
the 3 letters rot
do exist in combination in the list but not as an individual word. Testing for " rot " would fail but if one of the list items were "rot in hell", that would fail as well.
The upshot being, be careful with your search criteria if using this method and be aware that it does have this limitation.
这3个字母在列表中合并在一起,但不是作为一个单独的单词。对“rot”的测试将失败,但如果其中一个列表项是“rot in hell”,那也将失败。结果是,如果使用此方法,请小心使用您的搜索条件,并注意它确实有这个限制。
#13
3
One line solution:
一行的解决方案:
mylist = [{0: 'c', 1: 'd', 2: 'e', 3: 'f'}[i] for i in [0, 1, 2, 3] if i in (x, y, z)]
Or:
或者:
mylist = ['cdef'[i] for i in range(4) if i in (x, y, z)]
#1
522
You misunderstand how boolean expressions work; they don't work like an English sentence and guess that you are talking about the same comparison for all names here. You are looking for:
你误解了布尔表达式的工作原理;它们不像英文句子,而且猜你在这里谈论的是所有名字的相同比较。你正在寻找:
if x == 1 or y == 1 or z == 1:
x
and y
are otherwise evaluated on their own (False
if 0
, True
otherwise).
x和y单独计算(如果为0,则为False,否则为True)。
You can shorten that using a containment test against a tuple:
您可以对一个元组使用包含测试来缩短这个时间:
if 1 in (x, y, z):
or better still:
或者更好的是:
if 1 in {x, y, z}:
using a set
to take advantage of the constant-cost membership test (in
takes a fixed amount of time whatever the left-hand operand is).
使用一个集合来利用成本不变的成员关系测试(无论左手操作数是什么,in都需要固定的时间)。
When you use or
, python sees each side of the operator as separate expressions. The expression x or y == 1
is treated as first a boolean test for x
, then if that is False, the expression y == 1
is tested.
当您使用or时,python将操作符的每一面视为独立的表达式。表达式x或y == 1被视为对x的第一个布尔测试,如果这是错误的,那么表达式y == 1将被测试。
This is due to operator precedence. The or
operator has a lower precedence than the ==
test, so the latter is evaluated first.
这是由于操作符的优先级。or操作符的优先级比=测试低,因此首先计算后者。
However, even if this were not the case, and the expression x or y or z == 1
was actually interpreted as (x or y or z) == 1
instead, this would still not do what you expect it to do.
然而,即使不是这样,表达式x或y或z == 1实际上被解释为(x或y或z) = 1,这仍然不能实现预期的效果。
x or y or z
would evaluate to the first argument that is 'truthy', e.g. not False
, numeric 0 or empty (see boolean expressions for details on what Python considers false in a boolean context).
x或y或z将评估第一个参数是“truthy”,例如not False、numeric 0或empty(请参阅布尔表达式,以了解在布尔上下文中Python认为False的细节)。
So for the values x = 2; y = 1; z = 0
, x or y or z
would resolve to 2
, because that is the first true-like value in the arguments. Then 2 == 1
would be False
, even though y == 1
would be True
.
对于x = 2;y = 1;z = 0 x或y或z会分解为2,因为这是参数中的第一个真实值。然后2 == 1是假的,即使y = 1是真的。
The same would apply to the inverse; testing multiple values against a single variable; x == 1 or 2 or 3
would fail for the same reasons. Use x == 1 or x == 2 or x == 3
or x in {1, 2, 3}
.
反过来也一样;对单个变量测试多个值;x == 1或2或3会因为同样的原因而失败。使用x == 1或x = 2或x = 3或{1,2,3}中的x。
#2
47
Your problem is more easily addressed with a dictionary structure like:
你的问题更容易通过字典结构来解决,比如:
x = 0
y = 1
z = 3
d = {0: 'c', 1:'d', 2:'e', 3:'f'}
mylist = [d[k] for k in [x, y, z]]
#3
28
Previous Solution: As stated by Martijn Pieters, the correct, and fastest, format is:
先前的解决方案:正如Martijn Pieters所说,正确且最快的格式是:
if 1 in {x, y, z}:
The one major issue that does not seem to be addressed is that you want your output list to include each letter after a true if statement.
Using only Martijn Pieters' advice you would now have:
似乎没有解决的一个主要问题是,您希望您的输出列表在一个真实的if语句之后包含每个字母。只使用Martijn Pieters现在的建议:
if 0 in {x, y, z}:
Mylist.append("c")
elif 1 in {x, y, z}:
Mylist.append("d")
...
Problem: The first if statement would return true, and you would never get to the following elif statement. So your list would simply return:
问题:第一个if语句将返回true,您永远不会得到下面的elif语句。所以你的列表只会返回:
["c"]
What you want is to have separate if statements so that python will read each statement whether the former were true or false. Such as:
您需要的是有独立的if语句,以便python能够读取每个语句,无论前者是真还是假。如:
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")
...
This will work, but 'if' you are comfortable using dictionaries (see what I did there), you can clean this up by making an initial dictionary mapping the numbers to the letters you want, then just using a 'for' loop:
这是可行的,但是“如果”你喜欢使用字典(看看我在那里做了什么),你可以制作一个初始字典,将数字映射到你想要的字母,然后使用“for”循环:
numToLetters = {0:"c", 1:"d", 2:"e", 3:"f"}
for number in numToLetters:
if number in {x, y, z}:
Mylist.append(numToLetters[number])
#4
18
The direct way to write x or y or z == 0
is
直接写x或y或z == 0的方法。
if any(map((lambda value: value == 0), (x,y,z))):
pass # write your logic.
But I dont think, you like it. :) And this way is ugly.
但我不认为你喜欢它。这条路很难看。
The other way (a better) is:
另一个更好的方法是:
0 in (x, y, z)
BTW lots of if
s could be written as something like this
顺便说一句,很多if都可以写成这样
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
#5
15
If you ARE very very lazy, you can put the values inside an array. Such as
如果您非常非常懒,您可以将值放入一个数组中。如
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
You can also put the numbers and letters in a dictionary and do it, but this is probably a LOT more complicated than simply if statements. That's what you get for trying to be extra lazy :)
你也可以把数字和字母放到字典里去做,但是这可能比简单的if语句要复杂得多。这就是你试图变得特别懒惰的原因:
One more thing, your
一件事,你的
if x or y or z == 0:
will compile, but not in the way you want it to. When you simply put a variable in an if statement (example)
会编译,但不会按你想要的方式进行编译。当你在if语句中放入一个变量时(例如)
if b
the program will check if the variable is not null. Another way to write the above statement (which makes more sense) is
程序将检查变量是否为空。另一种写法(更有意义)是
if bool(b)
Bool is an inbuilt function in python which basically does the command of verifying a boolean statement (If you don't know what that is, it is what you are trying to make in your if statement right now :))
Bool是python中的一个内置函数,它基本上执行验证布尔语句的命令(如果您不知道它是什么,那么它就是您现在在If语句中要做的:)
Another lazy way I found is :
我发现的另一种懒惰的方式是:
if any([x==0, y==0, z==0])
#6
12
To check if a value is contained within a set of variables you can use the inbuilt modules itertools
and operator
.
要检查一个值是否包含在一组变量中,可以使用内置的模块itertools和操作符。
For example:
例如:
Imports:
进口:
from itertools import repeat
from operator import contains
Declare variables:
声明变量:
x = 0
y = 1
z = 3
Create mapping of values (in the order you want to check):
创建值的映射(按照您想要检查的顺序):
check_values = (0, 1, 3)
Use itertools
to allow repetition of the variables:
使用迭代工具允许重复变量:
check_vars = repeat((x, y, z))
Finally, use the map
function to create an iterator:
最后,使用map函数创建一个迭代器:
checker = map(contains, check_vars, check_values)
Then, when checking for the values (in the original order), use next()
:
然后,在检查值(按原始顺序)时,使用next():
if next(checker) # Checks for 0
# Do something
pass
elif next(checker) # Checks for 1
# Do something
pass
etc...
等等……
This has an advantage over the lambda x: x in (variables)
because operator
is an inbuilt module and is faster and more efficient than using lambda
which has to create a custom in-place function.
这比(变量)中的x: x有一个优点,因为操作符是一个内置模块,比使用lambda更快、更高效,lambda必须创建自定义的就地函数。
Another option for checking if there is a non-zero (or False) value in a list:
检查列表中是否有非零(或假)值的另一个选项:
not (x and y and z)
Equivalent:
相当于:
not all((x, y, z))
#7
12
Set is the good approach here, because it orders the variables, what seems to be your goal here. {z,y,x}
is {0,1,3}
whatever the order of the parameters.
Set是一个很好的方法,因为它对变量进行排序,这是你的目标。z,y,x}是{0,1,3}不管参数的顺序是什么。
>>> ["cdef"[i] for i in {z,x,y}]
['c', 'd', 'f']
This way, the whole solution is O(n).
这样,整个解就是O(n)
#8
11
I think this will handle it better:
我认为这样会更好:
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]
Output:
输出:
print validate(0, 8, 9)
c
print validate(9, 8, 9)
None
print validate(9, 8, 2)
e
#9
11
This code may be helpful
这段代码可能会有帮助
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;
#10
11
If you want to use if, else statements following is another solution:
如果你想使用If,下面的else语句是另一个解决方案:
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)
#11
10
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]
#12
10
All of the excellent answers provided here concentrate on the specific requirement of the original poster and concentrate on the if 1 in {x,y,z}
solution put forward by Martijn Pieters.
What they ignore is the broader implication of the question:
How do I test one variable against multiple values?
The solution provided will not work for partial hits if using strings for example:
Test if the string "Wild" is in multiple values
这里提供的所有优秀答案都集中在原始海报的具体要求上,集中在Martijn Pieters提出的{x,y,z}解决方案中的if 1。他们忽略了一个更广泛的问题:如何针对多个值测试一个变量?如果使用字符串(例如:测试字符串“Wild”是否在多个值中),所提供的解决方案将不能用于部分命中
>>> x="Wild things"
>>> y="throttle it back"
>>> z="in the beginning"
>>> if "Wild" in {x,y,z}: print (True)
...
or
或
>>> x="Wild things"
>>> y="throttle it back"
>>> z="in the beginning"
>>> if "Wild" in [x,y,z]: print (True)
...
for this scenario it's easiest to convert to a string
对于这个场景,最容易转换为字符串。
>>> [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
It should be noted however, as mentioned by @codeforester
, that word boundries are lost with this method, as in:
但是需要指出的是,正如@codeforester提到的,这种方法会丢失单词boundries,如:
>>> x=['Wild things', 'throttle it back', 'in the beginning']
>>> if "rot" in str(x): print(True)
...
True
the 3 letters rot
do exist in combination in the list but not as an individual word. Testing for " rot " would fail but if one of the list items were "rot in hell", that would fail as well.
The upshot being, be careful with your search criteria if using this method and be aware that it does have this limitation.
这3个字母在列表中合并在一起,但不是作为一个单独的单词。对“rot”的测试将失败,但如果其中一个列表项是“rot in hell”,那也将失败。结果是,如果使用此方法,请小心使用您的搜索条件,并注意它确实有这个限制。
#13
3
One line solution:
一行的解决方案:
mylist = [{0: 'c', 1: 'd', 2: 'e', 3: 'f'}[i] for i in [0, 1, 2, 3] if i in (x, y, z)]
Or:
或者:
mylist = ['cdef'[i] for i in range(4) if i in (x, y, z)]