【问题标题】:String Replace in csvcsv中的字符串替换
【发布时间】:2016-05-29 09:45:50
【问题描述】:

下面,我正在尝试替换 csv 中的数据。该代码有效,但它替换了文件中与 stocklevel 匹配的任何内容。

def updatestocklevel(quantity, stocklevel, code):
    newlevel = stocklevel - quantity
    stocklevel = str(stocklevel)
    newlevel = str(newlevel)
    s = open("stockcontrol.csv").read()
    s = s.replace (stocklevel ,newlevel) #be careful - will currently replace any number in the file matching stock level!
    f = open("stockcontrol.csv", 'w')
    f.write(s)
    f.close()

我的 csv 看起来像这样;

34512340,1
12395675,2
56756777,1
90673412,2
12568673,3
22593672,5
65593691,4
98593217,2
98693214,2
98693399,5
11813651,85
98456390,8
98555567,3
98555550,45
98553655,2
96553657,1
91823656,2
99823658,2

在我的程序的其他地方,我有一个搜索代码(8 位数字)的函数 是否可以说,如果code 在csv 的行中,则替换第二列中的数据? (数据[2])

【问题讨论】:

  • 那个“CSV”在哪里? CSV 代表“逗号分隔值”,对吧?
  • 是的,逗号在每行的 8 位代码之后。我刚从 excel @MarcusMüller 复制过来

标签: python python-3.x csv


【解决方案1】:

当您调用s.replace (stocklevel ,newlevel) 时,所有出现的stocklevel 都将替换为newlevel 的值。

string.replace(s, old, new[, maxreplace]): 返回字符串 s 的副本 将所有出现的子字符串 old 替换为 new。如果可选 参数 maxreplace 给出,第一个 maxreplace 出现是 替换了。

source

按照您的建议,您需要获取 code 并使用它来替换库存水平。

这是一个示例脚本,它将 8 位代码和新的库存水平作为命令行参数并替换它:

import sys
import re
code = sys.argv[1]
newval= int(sys.argv[2]) 
f=open("stockcontrol.csv")
data=f.readlines()
print data
for i,line in enumerate(data):
  if re.search('%s,\d+'%code,line): # search for the line with 8-digit code
    data[i]  = '%s,%d\n'%(code,newval) # replace the stock value with new value in the same line
f.close()

f=open("in.csv","w")
f.write("".join(data))
print data
f.close()

使用 Python 的csv 模块的另一种解决方案:

import sys
import csv

data=[]
code = sys.argv[1]
newval= int(sys.argv[2])
f=open("stockcontrol.csv")
reader=csv.DictReader(f,fieldnames=['code','level'])
for line in reader:
  if line['code'] == code:
    line['level']= newval
  data.append('%s,%s'%(line['code'],line['level']))
f.close()

f=open("stockcontrol.csv","w")
f.write("\n".join(data))
f.close()

警告:在尝试这些脚本时备份输入文件,因为它们会覆盖输入文件。

如果您将脚本保存在名为 test.py 的文件中,则调用它:

python test.py 34512340 10.

这应该将代码 34512340 的 stockvalue 替换为 10。

【讨论】:

  • 这两个都出现错误'code = sys.argv[1] IndexError: list index out of range'
  • @NathanShoesmith,你需要这样称呼它python <script> <code_to_be_modified> <newstockvalue>
  • 我不确定我知道你的意思@SilentMonk 吗?你能在代码中告诉我吗?
  • @NathanShoesmith,我已经编辑了建议如何调用它的答案。
  • 好的@SilentMonk,我已经将代码保存为test.py,但是调用它是什么意思??
【解决方案2】:

为什么不使用好的旧正则表达式?

import re

code, new_value = '11813651', '885' # e.g, change 85 to 885 for code 11813651
print (re.sub('(^%s,).*'%code,'\g<1>'+new_value,open('stockcontrol.csv').read()))

【讨论】:

  • 您可以在命令行中将输出通过管道传输到同一个文件,或者直接使用print (re.sub('(^%s,).*'%code,'\g&lt;1&gt;'+new_value,open('stockcontrol.csv').read()),file=open('stockcontrol.csv','w'))
【解决方案3】:

由于它是一个 csv 文件,我建议使用 Python 的 csv 模块。您将需要写入一个新文件,因为读取和写入同一个文件会变得很糟糕。您可以随时重命名它。

此示例使用StringIO (Python 2) 将您的 csv 数据嵌入代码中并将其视为文件。通常你会打开一个文件来获取输入。

更新

import csv
# Python 2 and 3
try:
    from StringIO import StringIO
except ImportError:
    from io import StringIO


CSV = """\
34512340,1
12395675,2
56756777,1
90673412,2
12568673,3
22593672,5
65593691,4
98593217,2
98693214,2
98693399,5
11813651,85
98456390,8
98555567,3
98555550,45
98553655,2
96553657,1
91823656,2
99823658,2
"""


def replace(key, value):
    fr = StringIO(CSV)
    with open('out.csv', 'w') as fw:
        r = csv.reader(fr)
        w = csv.writer(fw)

        for row in r:
            if row[0] == key:
                row[1] = value
            w.writerow(row)

replace('99823658', 42)

【讨论】:

  • '没有名为 StringIO 的模块'
  • @NathanShoesmith 更新了 python3.x 支持。
猜你喜欢
  • 1970-01-01
  • 2021-05-07
  • 1970-01-01
  • 1970-01-01
  • 2015-04-06
  • 2023-03-03
  • 1970-01-01
  • 2022-06-16
  • 2012-04-26
相关资源
最近更新 更多