带有 If Else 的 Python 嵌套列表理解

Dav*_*son 1 python list-comprehension

我试图使用列表理解来替换值列表中的多个可能的字符串值。

我有一个列名列表,这些列名取自cursor.description;

['UNIX_Time', 'col1_MCA', 'col2_MCA', 'col3_MCA', 'col1_MCB', 'col2_MCB', 'col3_MCB']
Run Code Online (Sandbox Code Playgroud)

然后我有header_replace;

{'MCB': 'SourceA', 'MCA': 'SourceB'}
Run Code Online (Sandbox Code Playgroud)

我想用值替换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])
Run Code Online (Sandbox Code Playgroud)

这给了我正确的输出;

['UNIX_Time', 'col1_SourceA', 'col2_SourceA', 'col3_SourceA', 'col1_SourceB', 'col2_SourceB', 'col3_SourceB']
Run Code Online (Sandbox Code Playgroud)

我尝试使用这个列表理解;

[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]
Run Code Online (Sandbox Code Playgroud)

但这意味着为不匹配的键复制了项目,我会得到;

['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']
Run Code Online (Sandbox Code Playgroud)

但如果我使用;

[str.replace(i[0],k,header_replace[k]) for k in header_replace.keys() for i in cursor.description if k in i[0]]
Run Code Online (Sandbox Code Playgroud)

@Bakuriu 固定语法

我会得到正确的替换,但随后会丢失任何不需要替换字符串的项目。

['col1_SourceA', 'col2_SourceA', 'col3_SourceA', 'col1_SourceB', 'col2_SourceB', 'col3_SourceB']
Run Code Online (Sandbox Code Playgroud)

是否有一种 pythonesque 方式来做这件事,或者我是否过度拉伸列表理解?我当然觉得它们很难读。

Bak*_*riu 6

[str.replace(i[0],k,header_replace[k]) if k in i[0] for k in header_replace.keys() for i in cursor.description]
Run Code Online (Sandbox Code Playgroud)

这是 a 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]]
Run Code Online (Sandbox Code Playgroud)

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])
Run Code Online (Sandbox Code Playgroud)

else对的for不当循环执行break的迭代过程中触发。


我不明白为什么在你的代码中你使用str.replace(string, substring, replacement)而不是string.replace(substring, replacement). 字符串具有实例方法,因此您可以使用它们,而不是将它们视为类的静态方法。