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

Python 在列表中组合多个条件表达式,python,list,unicode,conditional,list-comprehension,Python,List,Unicode,Conditional,List Comprehension,在将字符插入SQLite之前,我使用utf-8编码字符,如\u2013 当我用SELECT将它们拉出时,它们又回到了未编码的形式,所以如果我想对它们做任何事情,我需要对它们重新编码。在本例中,我希望将行写入CSV。在将行写入CSV之前,我希望首先将超链接添加到值以“http”开头的任何行。有些值将是整数、日期等,因此我使用条件表达式-列表理解组合: str()操作会产生众所周知的结果: UnicodeEncodeError:“ascii”编解码器无法在中对字符u'\u2013'进行编码 位置15

在将字符插入SQLite之前,我使用utf-8编码字符,如\u2013

当我用SELECT将它们拉出时,它们又回到了未编码的形式,所以如果我想对它们做任何事情,我需要对它们重新编码。在本例中,我希望将行写入CSV。在将行写入CSV之前,我希望首先将超链接添加到值以“http”开头的任何行。有些值将是整数、日期等,因此我使用条件表达式-列表理解组合:

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

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

然后,我需要再次执行
.encode('utf-8')
编码,但只对列表中以字符串开头的元素执行。以下操作无效(因为并非所有元素都是字符串):


TLDR:如何扩展/修改列表理解以仅对字符串元素进行编码?

通常,尽可能长时间使用unicode,并将unicode编码为 仅在必要时使用字节(即
str
s),例如将输出写入网络 套接字或文件

不要将
str
s与
unicode
混用——尽管这在Python2中是允许的, 它使Python2隐式地将
str
转换为
unicode
,或者根据需要使用
ascii
编解码器将其转换为
unicode
。如果隐式编码或解码失败,那么您将分别得到一个UNICODENCODINGERROR或UNICODEDCODINGERROR,比如您看到的那个

由于
cell
是unicode,请使用
u'=HYPERLINK(“{}”)。格式(cell)
u'=HYPERLINK(“%s”)“%cell
而不是
'=HYPERLINK(“%s”)“%cell
。(请注意,如果
单元格
包含双引号,则可能需要对
单元格
进行url编码)

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

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]

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

row = [cell.encode('utf-8') if isinstance(cell, unicode) else str(cell) 
       for cell in row]
然后你可以使用

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]

同样,由于
包含unicode格式的
单元格
s,因此执行测试

if u'http' in cell
使用
unicode
u'http'
而不是
str
,或者更好

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

尽管如果您将
'http'
保存在此处不会出现错误(因为
ascii
编解码器可以解码0-127范围内的字节),但无论如何使用
u'http'
都是一个很好的做法,因为它符合规则,从不混合
str
unicode
,并且支持心理清晰。

谢谢。但是如果cell.startswith(u'http')
到达一个
int
的单元格时(带有一个语法错误,因为
startswith
不是
int
的一种方法),它不会倒下吗?不确定您希望代码如何工作,因为如果
cell
中的
'http'是int,那么
cell
中的
'http'将引发类型错误……我正在检查
str(cell)
(不是
cell
)中的'http',并且由于
str()
操作接受
int
,因此工作正常。。。。直到我遇到了问题中的非ASCII字符。我已经完成了以下工作:
[u'=HYPERLINK({}”).format(cell)if(isinstance(cell,basestring)和cell中的“http”。encode('utf8'))else cell for cell for row]
。你的结论?看起来没问题,但经过进一步考虑,我认为首先将所有内容转换为
str
可能会使代码看起来更漂亮。然后,您可以删除
isinstance(cell,unicode)
复选框。“在将字符插入SQLite之前,我将utf-8编码为\u2013这样的字符。”;这是一件愚蠢的事情,因为SQLite很乐意存储Unicode。如果必须进行转换,请尽可能靠近输出。
if isinstance(cell, unicode) and cell.startswith(u'http')