如何在python中单行编写if和else

时间:2012-11-15 10:58:40

标签: python if-statement slice

  

可能重复:
  Ternary conditional operator in Python

我正在研究python并尝试将数据保存到数据库中 假设我有以下代码

conn = mdb.connect(user='root', passwd='redhat', db='Data', host='localhost', charset="utf8")

ex_li = ['stri_one','stri_two','stri_three','stri_four']

if ex_li[0] != '':
    campaignID = ex_li[0]
else:
    campaignID = ''

if ex_li[1] != '':
    keywordID = ex_li[1]
else:
    keywordID = ''
.........
.......

try:
    cursor = conn.cursor()
    query = "insert into PerformaceReport(campaignID, keywordID, keyword, avgPosition,cost)"
    query += "VALUES (%s, '%s', '%s', '%s')" %(campaignID, keywordID, keyword, avgPosition,cost)
    cursor.execute( query )
    conn.commit()
except Exception as e:
    print e,"!!!! Exception happend!!!!"

在上面的代码中,如果它们不等于空字符串,我将从列表中获取字符串,因为在切片期间如果没有字符串,它将显示list index out of range错误。

那么有没有办法在一行中编写这些if和else语句并将其作为值提交直接查询如下所示(仅作为一个想法)

        query += "VALUES (%s, '%s', '%s', '%s')" %(if ex_li[0] != '': campaignID = ex_li[0]  else: campaignID = '' ............)

5 个答案:

答案 0 :(得分:8)

expression_if_true if condition else expression_if_false

所以试试

campaignID = main_res[0] if ex_li[0] != '' else ''

答案 1 :(得分:1)

您可以使用this SO answer中的三元表达式(v2.5)。但我会建议:

names = ['campaignID', 'keywordID' ... ]  
data = itertools.izip_longest(names, ex_li)
key_string = ','.join(data.keys())
query = '...(' + key_string + ')...( %s, %s, %s, %s )' #no % here
cursor.execute(query, data.values())

说明:

在回答您修改后的问题时,您在其中测试ex_li[0]然后分配其值,没有必要检查空白并在找到它时分配,您可以这样做:

 campaignID = ex_li[0]

如果ex_li[0]'',那就是campaignID中的内容。你提到list index out of bounds,但除非你的列表长度不合适,否则在更新的代码中不会发生这种情况。

但是在更高级别,您可以完全删除这些if语句:

(campaignID, keywordID, ...) = ex_li

这是元组拆包。或者构建一个字典,这似乎更有用,因为您需要将ID视为数据和选择器:

names = ['campaignID', 'keywordID' ... ]  
data = zip(names, ex_li)
# now have data = {'campaignID': ex_li[0], ... }

您可以适当地构建您的查询:

query = 'insert into Performance report (' + ','.join(data.keys()) + ') ' +
        'values (' + ','.join("'"+elem+"'" for elem in data.values()) + ')'

一个改进可能是,如果你得到None而不是一个空字符串(它将成为'None'作为字符串),那么修改为zip读取的值:

data = zip(names, (elem or '' for elem in ex_li))

那应该给你空字符串而不是'无'。

如果thg435是正确的,你有时会得到一个较短的列表,那么你可以输入一些额外的''

data = zip(names, itertools.chain((elem or '' for elem in ex_li),
            itertools.repeat('')))

此处repeat将提供无尽的''列表,chain将从ex_li中获取元素,直到它用完为止,然后从''开始获取repeat {1}}。 zip运行直到一个或其他迭代器用完,因此当names耗尽时它将停止。或者,如果您希望单独处理None值,则可以izip_longest

data = itertools.izip_longest(names, ex_li)
key_string = ','.join(data.keys())
value_string = ','.join("'"+str+"'" for str in 
    (elem or '' for elem in data.values()))
query = '...(' + key_string + ')....(' + value_string + ')...'

或为了便于阅读:

def quotify(str):
    return "'"+str+"'"

然而,请勿这样做。在DB API中使用cursor.execute而不是自己引用值,因为许多SO问题都证明了这一点(例如Python: get escaped SQL string):

query = '...(' + key_string + ')...( %s, %s, %s, %s )' #no % here
cursor.execute(query, data.values())

这允许DB API为您正确地进行转义,防止注入攻击或事故。

答案 2 :(得分:0)

您可以尝试以下内容:

value_when_true if condition else value_when_false

答案 3 :(得分:0)

你也可以这样做:

campaignID = ex_li[0] and main_res[0] or ''

(当您的决定基于您评估为真或假的第一个值时起作用)

答案 4 :(得分:0)

query += "VALUES (%s, '%s', '%s', '%s')" %(ex_li[0] if ex_li[0] != '' else '', ............)

您无法像这样指定表达式的一部分,但您可以这样做:

campaignID = ex_li[0] if ex_li[0] != '' else ''
query += "VALUES (%s, '%s', '%s', '%s')" %(campaignID, ............)

如果您想保留引用并稍后使用campaignID