在列表推导中组合多个条件表达式

时间:2016-02-20 21:53:07

标签: python list unicode conditional list-comprehension

我将utf-8编码为 \ u2013 之类的字符,然后再插入SQLite。

当我用SELECT将它们拉出来时,它们又以未编码的形式返回,所以如果我想对它们做任何事情,我需要对它们进行重新编码。在这种情况下,我想将行写入CSV。在将行写入CSV之前,我想首先将超链接添加到值为“http”的任何行。一些值将是整数,日期等,所以我做了以下条件表达式 - 列表理解组合:

row = ['=HYPERLINK("%s")' % cell if 'http' in str(cell) else cell for cell in row].

str()操作会产生众所周知的:

  

UnicodeEncodeError:'ascii'编解码器无法对字符u'\ u2013'进行编码   位置15:序数不在范围内(128)错误。

我需要的是再次执行.encode('utf-8')编码,但仅限于列表中以字符串开头的那些元素。以下内容不起作用(因为并非所有元素都是字符串):

['=HYPERLINK("%s")' % cell if 'http' in str(cell).encode('utf8') else cell.encode('utf8') for cell in row]

TLDR:如何扩展/修改列表推导以仅对元素进行编码(如果它是字符串?)

1 个答案:

答案 0 :(得分:1)

一般来说,尽可能使用unicode,并编码unicode 字节(即str s)仅在必要时,例如将输出写入网络 套接字或文件。

不要将strunicode混合 - 尽管Python2允许这样做, 它会导致Python2使用str编解码器隐式地将unicode转换为ascii,反之亦然。如果隐式编码或解码失败,则会分别得到UnicodeEncodingError或UnicodedDecodingError,例如您正在看到的那个。

由于cell是unicode,因此请使用u'=HYPERLINK("{}")'.format(cell)u'=HYPERLINK("%s")' % cell代替'=HYPERLINK("%s")' % cell。 (请注意,如果cell包含双引号,您可能需要对cell进行网址编码。

row = [u'=HYPERLINK("{}")'.format(cell) 
       if isinstance(cell, unicode) and cell.startswith(u'http') else cell 
       for cell in row]

稍后,当/如果您需要将row转换为str时,您可以使用

row = [cell.encode('utf-8') if isinstance(cell, unicode) else str(cell) 
       for cell in row]

或者,首先将row中的所有内容转换为str

row = [cell.encode('utf-8') if isinstance(cell, unicode) else str(cell) 
       for cell in row]

然后你可以使用

row = ['=HYPERLINK("{}")'.format(cell) if cell.startswith('http') else cell 
       for cell in row]

同样,由于row包含cell是unicode,因此执行测试

if u'http' in cell

使用unicode u'http'代替str 'http',或者更好,

if isinstance(cell, unicode) and cell.startswith(u'http')

虽然如果你在这里保留'http'没有错误(因为ascii编解码器可以解码0-127范围内的字节),不管怎样,最好使用u'http'符合规则永远不会混合strunicode,并支持精神清晰。