简体   繁体   English

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

[英]Python Nested List Comprehension with If Else

I was trying to use a list comprehension to replace multiple possible string values in a list of values. 我试图使用列表推导来替换值列表中的多个可能的字符串值。

I have a list of column names which are taken from a cursor.description ; 我有一个来自cursor.description的列名列表;

['UNIX_Time', 'col1_MCA', 'col2_MCA', 'col3_MCA', 'col1_MCB', 'col2_MCB', 'col3_MCB']

I then have header_replace ; 然后我有header_replace ;

{'MCB': 'SourceA', 'MCA': 'SourceB'}

I would like to replace the string values for header_replace.keys() found within the column names with the values. 我想用这些值替换在列名中找到的header_replace.keys()的字符串值。

I have had to use the following loop; 我不得不使用以下循环;

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])

Which gives me the correct output; 这给了我正确的输出;

['UNIX_Time', 'col1_SourceA', 'col2_SourceA', 'col3_SourceA', 'col1_SourceB', 'col2_SourceB', 'col3_SourceB']

I tried using this list comprehension; 我尝试使用此列表理解;

[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]

But it meant that items were duplicated for the unmatched keys and I would get; 但这意味着要为不匹配的密钥复制项目,我会得到;

['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']

But if instead I use; 但是,如果我使用;

[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 fixed syntax @Bakuriu固定语法

I would get the correct replacement but then loose any items that didn't need to have an string replacement. 我会得到正确的替换,但是然后松开不需要替换字符串的所有项目。

['col1_SourceA', 'col2_SourceA', 'col3_SourceA', 'col1_SourceB', 'col2_SourceB', 'col3_SourceB']

Is there a pythonesque way of doing this or am I over stretching list comprehensions? 有没有做到这一点的怪诞方式,还是我过度扩展列表理解力? I certainly find them hard to read. 我当然觉得它们很难阅读。

[str.replace(i[0],k,header_replace[k]) if k in i[0] for k in header_replace.keys() for i in cursor.description]

this is a SyntaxError , because if expressions must contain the else part. 这是一个SyntaxError ,因为if表达式必须包含else部分。 You probably meant: 您可能的意思是:

[i[0].replace(k, header_replace[k]) for k in header_replace for i in cursor.description if k in i[0]]

With the if at the end. if结尾。 However I must say that list-comprehension with nested loops aren't usually the way to go. 但是我必须说,嵌套循环的列表理解通常不是要走的路。 I would use the expanded for loop. 我将使用扩展的for循环。 In fact I'd improve it removing the replaced flag: 实际上,我会改进它以除去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])

The else of the for loop is executed when no break is triggered during the iterations. 如果在迭代过程中未触发break则执行for循环的else


I don't understand why in your code you use str.replace(string, substring, replacement) instead of string.replace(substring, replacement) . 我不明白为什么在您的代码中使用str.replace(string, substring, replacement) string.replace(substring, replacement) str.replace(string, substring, replacement)而不是string.replace(substring, replacement) Strings have instance methods, so you them as such and not as if they were static methods of the class. 字符串具有实例方法,因此就这样使用它们,而不是像它们是类的静态方法一样。

If your data is exactly as you described it, you don't need nested replacements and can boil it down to this line: 如果您的数据完全符合您的描述,则不需要嵌套替换,可以将其简化为以下一行:

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']

I guess a function will be more readable: 我猜一个函数将更具可读性:

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)

Another (less readable) option: 另一个(不太可读)的选项:

import re
rx = '|'.join(header_replace)
print [re.sub(rx, lambda m: header_replace[m.group(0)], name) for name in names]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM