我试图使用列表推导来替换值列表中的多个可能的字符串值。
我有一个列名列表,这些列名取自cursor.description
;
['UNIX_Time', 'col1_MCA', 'col2_MCA', 'col3_MCA', 'col1_MCB', 'col2_MCB', 'col3_MCB']
然后我header_replace
;
{'MCB': 'SourceA', 'MCA': 'SourceB'}
我想将列名称中找到的header_replace.keys()
的字符串值替换为值。
我不得不使用以下循环;
headers = []
for header in cursor.description:
replaced = False
for key in header_replace.keys():
if key in header[0]:
headers.append(str.replace(header[0], key, header_replace[key]))
replaced = True
break
if not replaced:
headers.append(header[0])
这给了我正确的输出;
['UNIX_Time', 'col1_SourceA', 'col2_SourceA', 'col3_SourceA', 'col1_SourceB', 'col2_SourceB', 'col3_SourceB']
我尝试使用此列表理解;
[str.replace(i[0],k,header_replace[k]) if k in i[0] else i[0] for k in header_replace.keys() for i in cursor.description]
但这意味着对于不匹配的密钥,项目是重复的,我会得到;
['UNIX_Time', 'col1_MCA', 'col2_MCA', 'col3_MCA', 'col1_SourceA', 'col2_SourceA', 'col3_SourceA',
'UNIX_Time', 'col1_SourceB', 'col2_SourceB', 'col3_SourceB', 'col1_MCB', 'col2_MCB', 'col3_MCB']
但如果相反我使用;
[str.replace(i[0],k,header_replace[k]) for k in header_replace.keys() for i in cursor.description if k in i[0]]
@Bakuriu修复语法
我会得到正确的替换品,但随后松开任何不需要替换字符串的物品。
['col1_SourceA', 'col2_SourceA', 'col3_SourceA', 'col1_SourceB', 'col2_SourceB', 'col3_SourceB']
是否有这样做的pythonesque方式或我是否超过了列表推导?我当然觉得它们难以阅读。
答案 0 :(得分:4)
[str.replace(i[0],k,header_replace[k]) if k in i[0] for k in header_replace.keys() for i in cursor.description]
这是SyntaxError
,因为if
表达式必须包含else
部分。你可能意味着:
[i[0].replace(k, header_replace[k]) for k in header_replace for i in cursor.description if k in i[0]]
最后if
。但是我必须说嵌套循环的列表理解通常不是可行的方法。
我会使用扩展的for
循环。实际上我会改进它删除replaced
标志:
headers = []
for header in cursor.description:
for key, repl in header_replace.items():
if key in header[0]:
headers.append(header[0].replace(key, repl))
break
else:
headers.append(header[0])
在迭代期间没有触发else
时,执行for
循环的break
。
我不明白为什么在您的代码中使用str.replace(string, substring, replacement)
代替string.replace(substring, replacement)
。字符串有实例方法,所以你就这样,而不是它们是类的静态方法。
答案 1 :(得分:1)
如果您的数据与您描述的完全一致,则不需要嵌套替换,并且可以将其归结为此行:
l = ['UNIX_Time', 'col1_MCA', 'col2_MCA', 'col3_MCA', 'col1_MCB', 'col2_MCB', 'col3_MCB']
[i.replace('_MC', '_Source') for i in l]
>>> ['UNIX_Time',
>>> 'col1_SourceA',
>>> 'col2_SourceA',
>>> 'col3_SourceA',
>>> 'col1_SourceB',
>>> 'col2_SourceB',
>>> 'col3_SourceB']
答案 2 :(得分:0)
我想一个函数会更具可读性:
def repl(key):
for k, v in header_replace.items():
if k in key:
return key.replace(k, v)
return key
print map(repl, names)
另一个(不太可读)选项:
import re
rx = '|'.join(header_replace)
print [re.sub(rx, lambda m: header_replace[m.group(0)], name) for name in names]