0

i have to ignore some lines and replace some words in a csv, i tried using the following to replace but it looks like it gets ignored

if "myword" not in line:

to replace text i used

csv_writer.writerow(line.replace("oldword", "newword")) 

but this gets an error does someone knows why? EDIT WITH CODE

import csv

with open(r'excelfile.csv') as csv_file:
    csv_reader = csv.DictReader(csv_file)

    with open('new_names.csv', 'w', newline='') as new_file:
        fieldnames = ['value', 'type', 'description']
        writer=csv.writer(new_file)

        csv_writer =csv.DictWriter(new_file, fieldnames=fieldnames, delimiter= ',', extrasaction='ignore')

        csv_writer.writeheader()

        for line in csv_reader:
                csv_writer.writerow(line)
Pixil
  • 5
  • 3
  • 2
    Please show the full contents of line, and create a minimum reproducible example that we can just cut and paste to run on out own machines. Without seeing at least a minimal example of your data, I don't think we can answer this question. – joanis Feb 16 '22 at 16:42
  • i edited the post with the code – Pixil Feb 16 '22 at 16:52
  • This is the code without the 2 lines that i need to add in order to let it work – Pixil Feb 16 '22 at 16:52
  • OK, that's helpful, now can you show where you want to put the broken lines, the actual contents of `line` when they don't work, and what you would like them to do? I'd like to be able to reproduce the incorrect behaviour you're having trouble with. – joanis Feb 16 '22 at 16:54
  • i want to delete the lines with the word i don't need and replace the words during the copy of the csv to a new one, so i wanted to put the 2 lines of code after "for line in csv_reader:" – Pixil Feb 16 '22 at 16:59
  • So, because you're using a `csv.DictReader`, the values are nested in a dictionary structure. For example, if the file has a line that reads `has myword,and oldword,foo`, the `line` variable will contain `OrderedDict([('value', 'has myword'), ('type', 'and oldword'), ('description', 'foo')])`. So your tests have to be taking that into account. – joanis Feb 16 '22 at 18:24
  • always put full error message (starting at word "Traceback") in question (not in comments) as text (not screenshot, not link to external portal). There are other useful information. – furas Feb 16 '22 at 18:27
  • maybe first use `print()` and `print(type(...))` to see what you really have in variables. It is called `"print debuging"` and it helps to see what can be the problem. – furas Feb 16 '22 at 18:28
  • Thanks i will try the fix as soon as possible and try it – Pixil Feb 16 '22 at 20:48

1 Answers1

0

Because you're using a csv.DictReader, the values are nested in a dictionary structure. For example, if the file has a line that reads:

has myword,and oldword,foo

the line variable will contain:

OrderedDict([('value', 'has myword'), ('type', 'and oldword'), ('description', 'foo')])

Just like @furas suggested in the comments, I determined this by adding print(line) in the for line... loop.

So your logical tests have to be taking that into account.

Here are a few examples that you can adapt to fit your exact purpose:

import csv

with open(r'excelfile.csv') as csv_file:
    csv_reader = csv.DictReader(csv_file)

    with open('new_names.csv', 'w', newline='') as new_file:
        fieldnames = ['value', 'type', 'description']
        writer=csv.writer(new_file)

        csv_writer =csv.DictWriter(new_file, fieldnames=fieldnames, delimiter= ',', extrasaction='ignore')

        csv_writer.writeheader()

        for line in csv_reader:
            # Substitute oldword by newword in all values in line
            line = {k: v.replace("oldword", "newword") for k, v in line.items()}

            # Reject line if any value in line is exactly "myword":
            if "myword" not in line.values():
                csv_writer.writerow(line)

            # Reject line if any value in line contains "myword" as a substring:
            if not any("myword" in value for value in line.values()):
                csv_writer.writerow(line)
joanis
  • 10,635
  • 14
  • 30
  • 40
  • Thanks everyone for the help! – Pixil Feb 16 '22 at 20:47
  • OK this worked thanks, but what if i wanted more words to be rejected? – Pixil Feb 17 '22 at 07:40
  • Matching multiple strings has been asked before. For example, https://stackoverflow.com/q/4953272/3216427 might help, or maybe https://stackoverflow.com/q/54481198/3216427 – joanis Feb 17 '22 at 14:12