【问题标题】:Using multiple (similar) generator expressions使用多个(相似的)生成器表达式
【发布时间】:2023-03-25 04:49:01
【问题描述】:

在 csv 文件中,我试图用其他字符替换某些字符。

我现在的代码是这样的:

import csv

set1 = set('abc')
set2 = set('def')
set3 = set('ghi')

with open(path, 'r') as input, open(path2, 'w') as output:
    reader = csv.reader(input)
    writer = csv.writer(output)

    for row in reader:
            newrow = row
            newrow = [''.join('x' if c in set1 else c for c in item) for item in newrow]
            newrow = [''.join('y' if c in set2 else c for c in item) for item in newrow]
            newrow = [''.join('z' if c in set3 else c for c in item) for item in newrow]

            writer.writerow(newrow)

在这个例子中,我只使用了三个生成器表达式,但很容易不止这些。

有人知道正确的方法吗?我担心这种结构可能不是最快的(当然看起来也不是最优的)。

【问题讨论】:

  • @MartijnPieters:哎呀!我错过了。睡眼惺忪,我害怕

标签: python csv replace generator generator-expression


【解决方案1】:

str.translate 可能是合适的;类似于

replacements = [
    ('abc', 'x'),
    ('def', 'y'),
    ('ghi', 'z'),
]

trans = str.maketrans({ k: v for l, v in replacements for k in l })

new_row = [item.translate(trans) for item in row]

【讨论】:

  • 今晚又试了一次,成功了!这是执行速度最快的。
【解决方案2】:

您可以使用循环并参数化不同的部分:

newrow = row
for v, s in (('x', set1), ('y', set2), ('z', set3)):
    newrow = [''.join(v if c in s else c for c in item) for item in newrow]

如果要替换字符,请不要使用集合,而是使用映射:

mapping = dict.fromkeys(set1, 'x')
mapping.update(dict.fromkeys(set2, 'y'))
mapping.update(dict.fromkeys(set3, 'z'))
for row in reader:
    newrow = [''.join(mapping.get(c, c) for c in item) for item in newrow]

【讨论】:

  • 答案的第二部分是我正在寻找的(执行速度更快)。
【解决方案3】:

这是以某种方式结合了两个答案并且效果很好(比问题中的代码快几倍):

replacements = [
('abc', 'x'),
('def', 'y'),
('ghi', 'z'),
]

mapping = {a: b for c, b in replacements for a in c}

for row in reader:
    newrow = [''.join(mapping.get(c, c) for c in item) for item in row]
    writer.writerow(newrow)

【讨论】:

  • 你不必在字典上使用dict()。无论如何,很抱歉问,但有理由不使用字符串翻译表吗?这与 Martijn Pieters 的答案相同,但专门针对字符串。
  • 我已经相应地调整了我的答案并再次尝试了您的解决方案(见评论)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-06-20
  • 2018-05-02
  • 1970-01-01
  • 1970-01-01
  • 2018-09-01
  • 1970-01-01
  • 2019-08-11
相关资源
最近更新 更多