Python字典赋值使用map和lambda函数

5

我只是好奇是否可以使用map()函数代替for循环来实现以下循环?如果可以,请友好地展示一下如何实现? 或者,有什么更有效率的方法来实现以下操作?

f = open('sample_list.txt').read().split('\n')

val =   lambda x: re.match('[a-zA-z0-9]+',x).group() if x else None

for line in f:
    if line.find('XYZ') == -1:
        dict[val(line)]=0
    else:
        dict[val(line)]=1

这个程序读取的文件格式如下:

ABCD XYZ 
DEFG ABC

然后创建一个以第一个单词为键的字典,如果第二个值为 XYZ,则将其赋值为 1,否则为 0。

例如,该字典将如下所示:

{'ABCD': 1, 'DEFG': 0}

更新:

我对@shx2@arekolek提出的方法进行了计时, 字典推导法更快,而@arekolek的方法比任何方法都要快得多,因为它不使用我声明的val() lambda函数。

代码如下:

def a():
    return {
    val(line) : 0 if line.find('XYZ') == -1 else 1
    for line in f
    }

def b():
    return dict(map(lambda x: (x[0], int(x[1] == 'XYZ')), map(str.split, f)))

def c():
    return {k: int(v == 'XYZ') for k, v in map(str.split, f)}

print 'a='+timeit.timeit(a)
print 'b='+timeit.timeit(b)
print 'c='+timeit.timeit(c)

结果:

a = 13.7737597283
b = 6.82668938135
c = 3.98859187269

感谢您们的分享 :)
2个回答

5
最好使用字典推导而不是map
可以这样做:
my_dict = {
    val(line) : 0 if line.find('XYZ') == -1 else 1
    for line in f
}

一些注释和改进:

  1. dict 不是 Python 中一个好的变量名。
  2. 简化表达式 0 if line.find('XYZ') == -1 else 1 的替代方案:
    • int(line.find('XYZ') != -1)(将 bool 转换为 int
    • 如果你可以将值保留为 boolline.find('XYZ') != -1
    • 'XYZ' in line(鸣谢:@JonClements)

为什么要在这里使用 str.find - 如果您只想检查包含关系并且不打算使用索引,那么 if not 'XYZ' in line 更符合 Python 风格... - Jon Clements
1
谢谢您的输入,这太棒了。 - CYAN CEVI

1
使用lambda表达式:
dict(map(lambda x: (x[0], int(x[1] == 'XYZ')), map(str.split, f)))

或者:

dict(map(lambda k, v: (k, int(v == 'XYZ')), *map(str.split, f)))

字典推导式:
{k: int(v == 'XYZ') for k, v in map(str.split, f)}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接