Python中的三元混淆
假设我的列表只有Python中的三元混淆,python,iteration,conditional-statements,ternary,Python,Iteration,Conditional Statements,Ternary,假设我的列表只有str和None,我想检查将降低的字符串分配到另一个变量中,但如果它是大写或无,则应将其呈现为无 检查None和str.isupper()的代码起作用: for i in [None,'foo',None,'FOO',None,'bar']: x = None if i is None or i.isupper() else i print x 但否定条件不起作用: for i in [None,'foo',None,'FOO',None,'bar']: x = i
str
和None
,我想检查将降低的字符串分配到另一个变量中,但如果它是大写或无,则应将其呈现为无
检查None
和str.isupper()的代码起作用:
for i in [None,'foo',None,'FOO',None,'bar']:
x = None if i is None or i.isupper() else i
print x
但否定条件不起作用:
for i in [None,'foo',None,'FOO',None,'bar']:
x = i if i is not None or i.isupper() else None
print x
它返回AttributeError
:
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
AttributeError: 'NoneType' object has no attribute 'isupper'
回溯(最近一次呼叫最后一次):
文件“”,第2行,在
AttributeError:“非类型”对象没有属性“isupper”
- 为什么会这样?
- 除了循环中的三元赋值,还有其他方法执行相同的操作吗?
您正在测试i是否为None或i.isupper()
。当i
为None
时,这不起作用:
(i is not None) or (i.isupper())
评价懒惰;首先计算左参数,只有当False
是第二个参数时,才计算左参数。如果i
为None
,则第一个表达式仅为False
,因此右侧表达式的计算结果仅为None.isupper()
改为使用和
,并否定isupper()
测试:
x = i if i is not None and not i.isupper() else None
上面的表达式是i is None或i.isupper()的正确逻辑反转
或者在原始表达式周围使用not(…)
:
x = i if not (i is None or i.isupper()) else None
因为您正在为
循环使用常规的,所以这里不需要使用条件表达式;将以下内容分配给现有循环变量i
,即可:
for i in [None,'foo',None,'FOO',None,'bar']:
if i and i.isupper():
i = None
print i
您正在测试i是否为None或i.isupper()
。当i
为None
时,这不起作用:
(i is not None) or (i.isupper())
评价懒惰;首先计算左参数,只有当False
是第二个参数时,才计算左参数。如果i
为None
,则第一个表达式仅为False
,因此右侧表达式的计算结果仅为None.isupper()
改为使用和
,并否定isupper()
测试:
x = i if i is not None and not i.isupper() else None
上面的表达式是i is None或i.isupper()的正确逻辑反转
或者在原始表达式周围使用not(…)
:
x = i if not (i is None or i.isupper()) else None
因为您正在为
循环使用常规的,所以这里不需要使用条件表达式;将以下内容分配给现有循环变量i
,即可:
for i in [None,'foo',None,'FOO',None,'bar']:
if i and i.isupper():
i = None
print i
在返回AttributeError
的代码中,这是因为如果i为none,它将继续执行或语句的第二部分并检查i.isupper()
,但是none
没有isupper()
方法,因此出现错误
我可以建议一种不同的方法吗
items = [None,'foo',None,'FOO',None,'bar']
def splitItems(items, test):
trueItems = []
falseItems = []
for item in items:
if test(item):
trueItems.append(item)
else:
falseItems.append(item)
return trueItems, falseItems
trueItems, falseItems = splitItems(items, lambda i:i is None or i.isupper())
print "uppercase or None:", trueItems
print "lowercase:", falseItems
# uppercase or None: [None, None, 'FOO', None]
# lowercase: ['foo', 'bar']
在返回AttributeError
的代码中,这是因为如果i为none,它将继续执行或语句的第二部分并检查i.isupper()
,但是none
没有isupper()
方法,因此出现错误
我可以建议一种不同的方法吗
items = [None,'foo',None,'FOO',None,'bar']
def splitItems(items, test):
trueItems = []
falseItems = []
for item in items:
if test(item):
trueItems.append(item)
else:
falseItems.append(item)
return trueItems, falseItems
trueItems, falseItems = splitItems(items, lambda i:i is None or i.isupper())
print "uppercase or None:", trueItems
print "lowercase:", falseItems
# uppercase or None: [None, None, 'FOO', None]
# lowercase: ['foo', 'bar']
我喜欢@Brionius编辑的答案,这里是一个更一般的形式,它从列表中返回一个条目的dict,由判别函数返回的值键入(可能返回的不仅仅是True或False)
给予:
{False: [None, None, None], True: ['foo', 'FOO', 'bar']}
{0: [None, None, None], 3: ['foo', 'FOO', 'bar']}
{False: [None, 'foo', None, None, 'bar'], True: ['FOO']}
{1: ['bar'], 2: ['foo', 'FOO'], None: [None, None, None]}
然后,Brionius的解决方案可以实施为:
def splitItems(seq, condition):
ret = groupByEval(seq, condition)
return ret.get(True,[]), ret.get(False,[])
我喜欢@Brionius编辑的答案,这里是一个更一般的形式,它从列表中返回一个条目的dict,由判别函数返回的值键入(可能返回的不仅仅是True或False)
给予:
{False: [None, None, None], True: ['foo', 'FOO', 'bar']}
{0: [None, None, None], 3: ['foo', 'FOO', 'bar']}
{False: [None, 'foo', None, None, 'bar'], True: ['FOO']}
{1: ['bar'], 2: ['foo', 'FOO'], None: [None, None, None]}
然后,Brionius的解决方案可以实施为:
def splitItems(seq, condition):
ret = groupByEval(seq, condition)
return ret.get(True,[]), ret.get(False,[])
三元运算符使代码更难读懂三元运算符使代码更难读懂我从来不使用条件表达式来表示副作用。@MartijnPieters你能解释一下你的意思吗?我不明白。条件表达式通常会产生一个值。但是您没有将其用于表达式结果。您正在使用它调用两个列表之一的.append()
。不要,在这种情况下只使用普通的if
/else
结构。你使用表达式结构是为了产生副作用,这会导致混淆。@MartijnPieters:好的-我觉得它并不混淆-它看起来就像if/else语句的速记/语法糖。但我会听从你的意见,改变它,无论哪种方式对我来说都很好。我从来不会用条件表达式来表示副作用。@MartijnPieters你能解释一下你的意思吗?我不明白。条件表达式通常会产生一个值。但是您没有将其用于表达式结果。您正在使用它调用两个列表之一的.append()
。不要,在这种情况下只使用普通的if
/else
结构。你使用表达式结构是为了产生副作用,这会导致混淆。@MartijnPieters:好的-我觉得它并不混淆-它看起来就像if/else语句的速记/语法糖。但我会听从你的,改变它,无论哪种方式对我来说都很好。