在列表理解中组合多个条件表达式 [英] Combining multiple conditional expressions in a list comprehension

查看:284
本文介绍了在列表理解中组合多个条件表达式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I utf-8 encode characters like \u2013 before inserting them into SQLite.

当我使用SELECT将它们拉出时,它们又恢复为未编码形式,因此,如果我想对它们进行任何操作,则需要重新对其进行编码.在这种情况下,我想将行写入CSV.在将行写入CSV之前,我想先将超链接添加到任何以'http'开头的行.一些值将是整数,日期等,因此我使用了条件表达式-列表理解组合:

When I pull them out with a SELECT, they are back in their unencoded form, so I need to re-encode them if I want to do anything with them. In this case, I want to write the rows to a CSV.Before writing the rows to CSV, I want to first add hyperlink to any row whose value starts with 'http'. Some values will be ints, dates etc, so I do the folliowing conditional expression - list comprehension combo:

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

str()操作将导致众所周知的结果:

The str() operation then results in the well-known:

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

UnicodeEncodeError: 'ascii' codec can't encode character u'\u2013' in position 15: ordinal not in range(128) error.

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

What I need then is to perform the .encode('utf-8') encoding again, but only on those elements in the lists that are strings to begin with. The following won't work (since not all elements are strings):

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

TLDR:如何扩展/修改列表理解以仅在元素为字符串的情况下进行编码?

TLDR: How do I expand /modify the list comprehension to only encode an element if it's a string?

推荐答案

通常,尽可能以unicode的形式工作,并将已编码的unicode编码为 字节(即str s)仅在必要时使用,例如将输出写入网络 套接字或文件.

In general, work in terms of unicode as long as possible, and encoded unicode to bytes (i.e. strs) only when necessary, such as writing output to a network socket or file.

请勿将strunicode混合使用-尽管Python2允许这样做, 它会导致Python2根据需要使用ascii编解码器将str隐式转换为unicode,反之亦然.如果隐式编码或解码失败,那么您将分别收到UnicodeEncodingError或UnicodedDecodingError,如您所看到的.

Do not mix strs with unicode -- although this is permitted in Python2, it causes Python2 to implicitly convert str to unicode or vice versa as necessary using the ascii codec. If the implicit encoding or decoding fails, then you get a UnicodeEncodingError or UnicodedDecodingError, respectively, such as the one you are seeing.

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

Since cell is unicode, use u'=HYPERLINK("{}")'.format(cell) or u'=HYPERLINK("%s")' % cell instead of '=HYPERLINK("%s")' % cell. (Note that you may want to url-encode cell in case cell contains a double quote).

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

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

Later, when/if you need to convert row to strs, you could use

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


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


Alternatively, convert everything in row to strs first:

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,因此请执行测试


Similarly, since row contains cells which are unicode, perform the test

if u'http' in cell

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

using the unicode u'http' instead of the str 'http', or better yet,

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

尽管在此处保留'http'不会出现任何错误(因为ascii编解码器可以解码0-127范围内的字节),但是还是要使用u'http',这是一个好习惯,因为要遵守该规则,请勿混用strunicode,并支持头脑清晰.

Although no error arises if you keep 'http' here (since the ascii codec can decode bytes in the 0-127 range), it is a good practice to use u'http' anyway since conforms to the rule never mix str and unicode, and supports mental clarity.

这篇关于在列表理解中组合多个条件表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆