0

I was trying to run a code that I wrote the code reads lines on txt file so my text file looks like (i've 20 lines)

['39', '40', '39', '38', '35', '38', '39', '39', '42', '37', '40', '41', '37', '39', '39', '40', '38', '40', '39', '40']

['39', '40', '39', '38', '36', '39', '40', '39', '42', '38', '40', '41', '38', '39', '39', '40', '38', '40', '39', '41']

['39', '40', '40', '38', '36', '39', '40', '39', '43', '38', '40', '41', '38', '39', '39', '40', '38', '40', '39', '41']

i wrote this script to have a new file that looks like this

39 40 39 38 35 38 39 39 42 37 40 41 37 39 39 40 38 40 39 40

39 40 39 38 36 39 40 39 42 38 40 41 38 39 39 40 38 40 39 41

39 40 40 38 36 39 40 39 43 38 40 41 38 39 39 40 38 40 39 41

the script that i wrote is this one

    #!/usr/bin/python3
# -*- coding: utf-8 -*-

fichier=open("data.txt", "r")
#resultat=open("data_entier.txt", "w")

j=0;

while j < 20:
    lignes= fichier.readline()
    for i in range(len(lignes)):
         lignes[i] = int(lignes[i])

    print(lignes))

    j+=1

fichier.close()

the error that I get is this one

ValueError: invalid literal for int() with base 10: '['

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
Driss Aourir
  • 37
  • 1
  • 2
  • 6
  • Looks like all you want to do is replace every occurence of ``[``, ``'``, ``,`` and ``]`` with an empty string, correct? For that, you don't need to convert anything to ``int``. – Mike Scotty Jul 19 '17 at 12:05
  • yea exactlly, how can i do that ? – Driss Aourir Jul 19 '17 at 12:07
  • where did `data.txt` come from? It seems you choose to dump lists there initially, rather than the format you actually wanted... – Chris_Rands Jul 19 '17 at 12:07
  • @DrissAourir https://stackoverflow.com/questions/6116978/python-replace-multiple-strings – Avión Jul 19 '17 at 12:08
  • data.txt is in the same folder as my .py its where my lines ar stored. – Driss Aourir Jul 19 '17 at 12:08
  • But how was `data.txt` generated? By you? – Chris_Rands Jul 19 '17 at 12:09
  • Possible duplicate of [Convert string representation of list to list in Python](https://stackoverflow.com/questions/1894269/convert-string-representation-of-list-to-list-in-python) – Rahul Jul 19 '17 at 12:09
  • @Chris_Rands yea by me the data in the file are actually temperature mesures of a 20 sensors that i have – Driss Aourir Jul 19 '17 at 12:13
  • @DrissAourir Well don't dump your lists to the file like that in the first place then! The suggested solutions are worse than sorting out your issue upstream – Chris_Rands Jul 19 '17 at 12:14
  • 1
    @Chris_Rands Good job breaking down the XY. :) At this point, yes, the best suggestion here would be to first generate the data in to the file properly to not have to face this kind of issue. Ultimately your data should have just been a dump of the numbers without their *list* representations in to the file. – idjaw Jul 19 '17 at 12:16
  • At this point, what is the best way to proceed with this? It would change the base nature of the question at this point. – idjaw Jul 19 '17 at 12:17
  • I added an "area of improvement" in my answer to help. – idjaw Jul 19 '17 at 12:21
  • And the downvote on this question is very unfair. There is an input, expected output, code, exact error and explanation of what is trying to be done. What else are we supposed to expect in terms of a worthy enough question for upvoting? – idjaw Jul 19 '17 at 12:28

4 Answers4

4

The problem is that when you read in readline from your file, you will have a line

"['39', '40', '39', '38', '35', '38', '39', '39', '42', '37', '40', '41', '37', '39', '39', '40', '38', '40', '39', '40']\n"

As you can see, the first item in your string is [. So, you don't actually have the numbers structured as you are expecting. Instead, since you seem to already have a list structure represented as a string, consider using literal_eval from ast:

>>> d = literal_eval(d)
>>> d
['39', '40', '39', '38', '35', '38', '39', '39', '42', '37', '40', '41', '37', '39', '39', '40', '38', '40', '39', '40']

Now you actually have a list of strings. Now you can proceed modifying that to your ints. As a simple process, you can then do something like this:

>>> converted_to_ints = map(int, d)
>>> print(list(converted_to_ints))
[39, 40, 39, 38, 35, 38, 39, 39, 42, 37, 40, 41, 37, 39, 39, 40, 38, 40, 39, 40]

Note, when it comes to using map in Python 3 you get a map object, which returns an iterator. So, if you need the list, this is why list is called when printing. You can read about it here:

https://docs.python.org/3/library/functions.html#map

Area of Improvement

Based on the contents of the file you are reading, it would be best to not structure the data like this. Instead, what should be done is not setting the data as a list representation in to the file, but just the contents of the list. This avoids having to perform the above solution, and instead, a simple:

with open('file.txt') as f:
  data = f.read().splitlines() # will remove newline character
  for line in data:
      # perform operations

would suffice.

idjaw
  • 25,487
  • 7
  • 64
  • 83
2

You are not evaluating the line as a list: every line is just a string that happens to start with a '['. So you are iterating over the characters of the line.

If the file is like you describe it however, you can easily evaluate the line with ast.literal_eval:

from ast import literal_eval

with open("data.txt", "r") as fichier:
    for line,_ in zip(fichier,range(20)):
        the_list = literal_eval(line)
        the_list = [int(x) for x in the_list]
        print(the_list))

We here used zip as a way to obtain the first 20 lines. If you want to process all the lines, you can simply use:

with open("data.txt", "r") as fichier:
    for line in fichier:
        the_list = literal_eval(line)
        the_list = [int(x) for x in the_list]
        print(the_list))
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
0

You're reading a line, so you can simply replace the chars you don't want.

string = "['39', '40', '39', '38', '35', '38', '39', '39', '42', '37', '40', '41', '37', '39', '39', '40', '38', '40', '39', '40']"
s = string.replace(',','').replace('[','').replace(']','').replace("'","")
print s
#output: 39 40 39 38 35 38 39 39 42 37 40 41 37 39 39 40 38 40 39 40
Víctor López
  • 819
  • 1
  • 7
  • 19
  • If you are going to go down that route, and knowing what each line looks like, you could have just done `string[1:-2]`. This will remove the first `[` and the trailing `]\n`. – idjaw Jul 19 '17 at 12:15
0

Although in this case the ast.literal_eval solutions presented by idjaw and Willem Van Onsem seem as an obvious best fit, let me present another solution:

numbers_text = "['39', '40', '39', '38', '35', '38', '39', '39', '42', '37', '40', '41', '37', '39', '39', '40', '38', '40', '39', '40']"

Instead of chaining multiple replace operations, you can use str.translate to get rid of multiple characters in one pass, by providing the third argument to str.maketrans:

If there is a third argument, it must be a string, whose characters will be mapped to None in the result.

Afterwards, we can either use a simple list comprehension to convert the separate numbers from str to int:

numbers_int = [int(x) for x in numbers_text.translate(str.maketrans("","","[',]")).split()]

Or make use of map:

numbers_int = list(map(int, numbers_text.translate(str.maketrans("","","[',]")).split()))

Both will result in a new list of int:

[39, 40, 39, 38, 35, 38, 39, 39, 42, 37, 40, 41, 37, 39, 39, 40, 38, 40, 39, 40]
Christian König
  • 3,437
  • 16
  • 28