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