我正在尝试创建一个函数,将多个变量与一个整数进行比较,并输出一个由三个字母组成的字符串。我想知道是否有办法将其翻译成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")
这将返回一个列表
["c", "d", "f"]
这样的事情可能吗?
你误解了布尔表达式的工作原理;他们不像英语句子一样工作,并猜测你在谈论所有名字的相同比较。您正在寻找:
if x == 1 or y == 1 or z == 1:
x
和y
另外进行评估(False
,如果0
,True
否则)。
您可以使用针对a tuple的包含测试来缩短它:
if 1 in (x, y, z):
或者更好的是:
if 1 in {x, y, z}:
使用a set
来利用常量成本隶属度测试(无论左手操作数是多少,in
都需要一段固定的时间)。
当您使用or
时,python将运算符的每一侧视为单独的表达式。表达式x or y == 1
首先被视为x
的布尔测试,然后如果为False,则测试表达式y == 1
。
这是由于operator precedence。 or
算子的优先级低于==
测试,因此后者首先被评估。
然而,即使不是这种情况,并且表达式x or y or z == 1
实际上被解释为(x or y or z) == 1
,这仍然不会做你期望它做的事情。
x or y or z
将评估第一个“truthy”的论点,例如:不是False
,数字0或空(有关Python在布尔上下文中认为false的详细信息,请参阅boolean expressions)。
所以对于值x = 2; y = 1; z = 0
,x or y or z
将解析为2
,因为这是参数中第一个类似真值的值。然后2 == 1
将是False
,即使y == 1
将是True
。
这同样适用于逆;针对单个变量测试多个值; x == 1 or 2 or 3
会因同样的原因而失败。使用x == 1 or x == 2 or x == 3
或x in {1, 2, 3}
。
这里提供的所有优秀答案都集中在原始海报的具体要求上,并专注于Martijn Pieters提出的if 1 in {x,y,z}
解决方案。
他们忽略的是这个问题的更广泛的含义:
如何针对多个值测试一个变量?
如果使用字符串,则提供的解决方案不适用于部分匹配:
测试字符串“Wild”是否为多个值
>>> x = "Wild things"
>>> y = "throttle it back"
>>> z = "in the beginning"
>>> if "Wild" in {x, y, z}: print (True)
...
要么
>>> x = "Wild things"
>>> y = "throttle it back"
>>> z = "in the beginning"
>>> if "Wild" in [x, y, z]: print (True)
...
对于这种情况,最容易转换为字符串
>>> [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
然而,应该注意的是,正如qazxsw poi所提到的那样,用这种方法会丢失单词边界,如:
@codeforester
3个字母>>> x=['Wild things', 'throttle it back', 'in the beginning']
>>> if "rot" in str(x): print(True)
...
True
确实在列表中组合存在但不作为单个单词存在。对“腐烂”的测试会失败,但如果其中一个列表项目“在地狱中腐烂”,那么也会失败。
结果是,如果使用此方法,请注意您的搜索条件,并注意它确实有此限制。
rot
此代码可能会有所帮助
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]
一线解决方案:
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;
要么:
mylist = [{0: 'c', 1: 'd', 2: 'e', 3: 'f'}[i] for i in [0, 1, 2, 3] if i in (x, y, z)]
您可以尝试下面显示的方法。在此方法中,您可以自由指定/输入要输入的变量数。
mylist = ['cdef'[i] for i in range(4) if i in (x, y, z)]
也许您需要设置输出位的直接公式。
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']
让我们映射到位: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
isc的关系(是'c'):
'c':1 'd':0xb10 'e':0xb100 'f':0xb1000
如果公式if xyz=0 then isc=1 else isc=0
使用数学
[c]:https://youtu.be/KAdKCgBGK0k?list=PLnI9xbPdZUAmUL8htSl6vToPQRRN3hhFp&t=315
[d]:(xyz=0 and isc=1) or (((xyz=0 and isc=1) or (isc=0)) and (isc=0))
...
按照以下逻辑连接这些公式:
((x-1)(y-1)(z-1)=0 and isc=2) or (((xyz=0 and isd=2) or (isc=0)) and (isc=0))
是方程的平方和and
是方程的乘积并且你将得到一个总方程式快速总和,你有总和的公式
sum&1是c,sum&2是d,sum&4是e,sum&5是f
在此之后,您可以形成预定义数组,其中字符串元素的索引将对应于就绪字符串。
or
给你字符串。
它可以轻松完成
array[sum]
在Python中表示伪代码的最常用的方法是:
for value in [var1,var2,var3]:
li.append("targetValue")
看起来你正在构建某种凯撒密码。
一个更通用的方法是这样的:
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")
输出
input_values = (0, 1, 3)
origo = ord('c')
[chr(val + origo) for val in inputs]
不确定它是否是您的代码所需的副作用,但输出的顺序将始终排序。
如果这是你想要的,最后一行可以改为:
['c', 'd', 'f']
使用单个值测试多个变量:sorted([chr(val + origo) for val in inputs])
使用一个变量测试多个值:if 1 in {a,b,c}:
使用字典结构更容易解决您的问题:
x = 0
y = 1
z = 3
d = {0: 'c', 1:'d', 2:'e', 3:'f'}
mylist = [d[k] for k in [x, y, z]]
你可以使用字典:
if a in {1, 2, 3}:
这会对你有所帮助。
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
正如Martijn Pieters所说,正确,快速的格式是:
if 1 in {x, y, z}:
使用他的建议你现在将有单独的if语句,以便Python将读取每个语句,无论前者是True
还是False
。如:
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")
...
这样可以工作,但是如果你习惯使用词典(看我在那里做了什么),你可以通过制作一个初始字典来将数字映射到你想要的字母,然后只使用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])
写x or y or z == 0
的直接方法是
if any(map((lambda value: value == 0), (x,y,z))):
pass # write your logic.
但我不认为,你喜欢它。 :)这种方式很难看。
另一种方式(更好)是:
0 in (x, y, z)
BTW很多if
s可以写成这样的东西
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
如果你非常懒,可以将值放在数组中。如
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
您也可以将数字和字母放在字典中并执行它,但这可能比简单的语句更复杂。这就是你想要更加懒惰的结果:)
还有一件事,你的
if x or y or z == 0:
将编译,但不是以你想要的方式编译。当你只是在if语句中放一个变量时(例子)
if b
程序将检查变量是否为空。编写上述语句的另一种方法(更有意义)是
if bool(b)
Bool是python中的一个内置函数,它基本上执行验证布尔语句的命令(如果你不知道那是什么,那么你现在正试着在你的if语句中做:) :)
我发现的另一种懒惰方式是:
if any([x==0, y==0, z==0])
要检查一组变量中是否包含值,可以使用内置模块itertools
和operator
。
例如:
进口:
from itertools import repeat
from operator import contains
声明变量:
x = 0
y = 1
z = 3
创建值的映射(按您要检查的顺序):
check_values = (0, 1, 3)
使用itertools
允许重复变量:
check_vars = repeat((x, y, z))
最后,使用map
函数创建迭代器:
checker = map(contains, check_vars, check_values)
然后,在检查值时(按原始顺序),使用next()
:
if next(checker) # Checks for 0
# Do something
pass
elif next(checker) # Checks for 1
# Do something
pass
等等...
这比lambda x: x in (variables)
有优势,因为operator
是一个内置模块,比使用必须创建自定义就地功能的lambda
更快更有效。
检查列表中是否存在非零(或False)值的另一个选项:
not (x and y and z)
当量:
not all((x, y, z))
我认为这会更好地处理它:
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]
输出:
print validate(0, 8, 9)
c
print validate(9, 8, 9)
None
print validate(9, 8, 2)
e
Set是一个很好的方法,因为它命令变量,这似乎是你的目标。无论参数的顺序如何,{z,y,x}
都是{0,1,3}
。
>>> ["cdef"[i] for i in {z,x,y}]
['c', 'd', 'f']
这样,整个解决方案就是O(n)。
如果你想使用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)