1

I am trying to sort an imported list then display it but I have tried all sorts of things and it didnt work.

Here is an exemple of the list:

pommes : 54
bananes : 18
oranges : 30


ananas :12
clémentines    :77
cerises de terre:    43

The output should be ordered alphabeticaly

This is what I am getting

['\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '0', '1', '1', '2',
 '3', '3', '4', '4', '5', '7', '7', '8', ':', ':', ':', ':', ':', ':', 'a', 'a', 'a', 'a', 'a', 'a', 'b', 'c', 'c', 'd', 'e', 'e', 'e', 'e', 'e', 'e', 'e', 'e'
, 'e', 'e', 'g', 'i', 'i', 'l', 'm', 'm', 'm', 'n', 'n', 'n', 'n', 'n', 'n', 'n', 'o', 'o', 'p', 'r', 'r', 'r', 'r', 's', 's', 's', 's', 's', 's', 's', 't', 't
', 'é']

Here's is my code

import sys

def liste(entree):
    try:
        ouvrir = open("data2.txt")
    except IOError:
        message1 = "Le fichier data2 n'existe pas."
        return message1
    lecture = ouvrir.read()
    if len(entree) < 1:
        message2 = "Il faut préciser le nom du fichier à traiter"
        return message2
    elif len(entree) > 1:
        message3 = "Un seul argument est attendu, soit le nom du fichier à traiter."
        return message3
    else:
        return lecture

def main():
    while True:
        entree = sys.argv[1:]
        choix = str(entree)
        texte = "data2.txt"
        if texte in choix:
            message4 = liste(entree)
            message4 = sorted(message4)
            print(message4)
            break
        else:
            print("Il faut préciser le nom du fichier à traiter")
            exit()

if __name__ == "__main__":
    main()
Isen
  • 79
  • 8
  • 2
    you may want to look at `readlines` instead – njzk2 Apr 14 '17 at 19:14
  • 1
    In the future, please try to produce the *shortest possible* program that demonstrates the same problem, as described in the Help Center page on creating a [mcve]. – Charles Duffy Apr 14 '17 at 19:20
  • sorry im trying to be as clear as possible – Isen Apr 14 '17 at 19:26
  • Please provide an example of the first few lines of your input file, it appears from some of your comments that you have input that has something like, "Apple: 23". – ChuckCottrill Apr 15 '17 at 02:34

3 Answers3

2

You need to use the readlines method here, which reads the lines into a list, rather than read method which returns all contents into a string.

lecture = ouvrir.readlines()

Final program:

import sys

def liste(entree):
    try:
        ouvrir = open("data2.txt")
    except IOError:
        message1 = "Le fichier data2 n'existe pas."
        return message1
    lecture = ouvrir.readlines()
    if len(entree) < 1:
        message2 = "Il faut préciser le nom du fichier à traiter"
        return message2
    elif len(entree) > 1:
        message3 = "Un seul argument est attendu, soit le nom du fichier à traiter."
        return message3
    else:
        return lecture

def main():
    while True:
        entree = sys.argv[1:]
        choix = str(entree)
        texte = "data2.txt"
        if texte in choix:
            message4 = liste(entree)
            print(message4)
            message4 = sorted(message4)
            print(message4)
            break
        else:
            print("Il faut préciser le nom du fichier à traiter")
            exit()

if __name__ == "__main__":
    main()

Run this:

$ python3 french-program.py data2.txt                                                                         
['Orange\n', 'Apple\n', 'Banada']
['Apple\n', 'Banada', 'Orange\n']
Ananth
  • 4,227
  • 2
  • 20
  • 26
  • yes it's giving me this answer, but how can i do to make the output actualy looks like in my question up above. There shjouldn'T be any \n and ,. I guess i have to use a .split somewhere. Whats the way i can use to format the result exactly like i want. – Isen Apr 14 '17 at 19:51
1

Try readlines, (see this answer: How do I read a file line-by-line into a list?, also see: Reading a text file and splitting it into single words in python).

Oh, and 'with open()' is idiomatic (moreso than try),

with open("data2.txt") as ouvrir:
    lines = ouvrir.readlines()
print sorted(lines)

Assuming each line contains a single word, you are done.

Suppose you want to treat each line as words (one or more words per line), sort the words on each line, and sort the lines,

#open file "data2.txt" and readlines into list
#split each line into words and sort that list of sorted lines
#words = list ( list ( word ) )
with open("data2.txt") as ouvrir:
    lines = ouvrir.readlines()
    line_words = [ x for x in [ line.split(":") for line in lines ] ]
    #line_names = [ x[0] for x in [ line.split(":") for line in lines ] ]
print sorted(line_words)

Suppose each line has one or more words, and you want a sorted list of words? The following flattens the nested list of words into a single list of words,

#open file "data2.txt" and readlines into list
#split each line into words, flatten into single list of words
#words = list ( word )
with open("data2.txt") as ouvrir:
    lecture = ouvrir.readlines()
    words = [ word for line in lecture for word in line.split() ]
print sorted(words)

Suppose your lines have key:value pairs, e.g. "Apple: 23"?, then you want something different

Your program combines examining entree (slice sys.argv[1:]) with opening and reading a file. You should separate those two functions. Here is one way to revise your code,

import sys

def liste(texte,entree):
    if len(entree) < 1:
        return "Il faut préciser le nom du fichier à traiter"
    elif len(entree) > 1:
        return "Un seul argument est attendu, soit le nom du fichier à traiter."
    with open(texte) as ouvrir:
        lecture = ouvrir.readlines()
        words = [ x.split(":")[0].strip() for x in [ line.strip() for line in lecture ] ]
        words = [ x for x in words if len(x) > 1 ] #filter, remove short words (blanks)
        return lecture
    return "Le fichier {} n'existe pas.".format(texte)

def main():
    while True:
        entree = sys.argv[1:]
        choix = str(entree)
        texte = "data2.txt"
        if texte in choix:
            message4 = sorted(liste(texte,entree))
            print(message4)
            for el in message4: print(el)
            break
        else:
            print("Il faut préciser le nom du fichier à traiter")
            break

if __name__ == "__main__":
    main()
    exit()
Community
  • 1
  • 1
ChuckCottrill
  • 4,360
  • 2
  • 24
  • 42
  • i don't really understand the word = ..... What is it supose to do in my code? Atm i've tried the solution under your's but im stuck with a wrong result with "," and [] . Will it fix this? – Isen Apr 15 '17 at 00:20
  • in the first exemple you gave me what is the X supose to do. Also in the second i dont understand the variable fh. Can you give me how it can be integrated into my code with the variables im using because nothing work on my side > – Isen Apr 15 '17 at 01:43
  • Sure, I will annotate. The [ x for x in list ] construct is a list comprehension, and the first x is the item you are placing into the list you are building in the list comprehension -- I will edit the answer to add how to revise your code... – ChuckCottrill Apr 15 '17 at 01:55
  • there's something not working with the exemple of code you gave me. – Isen Apr 15 '17 at 04:48
  • Ah, I see from your revised example data, that you have lines of the form, "key : value". Then you want to use the list comprehension that does the split(":"), and you want to trim the spaces off the strings. – ChuckCottrill Apr 15 '17 at 06:02
  • i am trying to understand why we arent using the variable words anywhere else. Also i dont understand why my elif len(entree) > 1: isnt working anymore its getting sorted. Ive trying putting it in an other function and calling it in the main b4 the for but it isnt working – Isen Apr 15 '17 at 14:05
  • Im also trying to remove these spaces with the command. I'am trying to apply it to mots but it isnt working again... all these white space are sorted at the beggining of the result and its printing this again. exemple:['', '', '', 'ananas', 'bananes', 'cerises de terre', 'clémentines', 'oranges', 'pommes'] im having big difficulties with that part of strings manipulations. – Isen Apr 15 '17 at 14:41
  • The empty strings are due to the file format, and probably empty lines. There is a version of list comprehension where you can filter the list to remove these blanks - http://stackoverflow.com/questions/7623715/deleting-list-elements-based-on-condition, http://stackoverflow.com/questions/3900215/ignore-an-element-while-building-list-in-python – ChuckCottrill Apr 16 '17 at 05:47
1

Your statements

ouvrir = open("data2.txt")
lecture = ouvrir.read()

works like this: open("data2.txt") returns a file object that you label with the name ouvrir, the method .read() returns a string coinciding with the contents of "data2.txt" and you label this string as lecture.

When you reference lecture you reference a string and not a list...

A clever way to solve the problem uses a string method: splitlines(); it takes a string and returns a list whose elements are strings obtained by splitting the original string across newlines.

lecture = ouvrir.read()        # lecture is a string
lecture = lecture.splitlines() # lecture is now a list of strings (lines)

and this is what you need to keep going. Please note that, as the original content is splitted on newlines, no newlines (i.e., '\n' characters) are present any more in the lines you are going to sort...

To complete my answer I have to mention that methods can be chained

lecture = ouvrir.read().splitlines()

Addendum

Another possibility leaves alone your liste() function (note that liste is a misleading name, as your function returns a string, not a list...) and post-process the string returned by liste — or I'd rather say, other possibilities even if "There should be one-- and preferably only one --obvious way to do it"...

(...)
       if texte in choix:
            message4 = liste(entree)          ## m4 is a string of characters
            message4 = message4.splitlines()  ## m4 is a list of strings,
                                              ##    one string <-> one line in file
            message4 = sorted(message4)       ## m4 contents are sorted now

            for line in message4:             ## let's do something for each line in m4
                if line:                      ## that is, if the line contains something
                    print(line)
            print('############################# alternative')
            lines = sorted(l for l in liste(entree).splitlines() if l)
            for line in lines: print(line)
            print('############################# alternative')
            for line in sorted(l for l in liste(entree).splitlines() if l): print(line)
            print('############################# alternative')
            print('\n'.join(sorted(l for l in liste(entree).splitlines() if l)))
            break
        else:
(...)
gboffi
  • 22,939
  • 8
  • 54
  • 85
  • Hi, this is working but it's gnot giving met he right answer i posted above. It's giving me.['', '', '', 'ananas :12', 'bananes : 18', 'cerises de terre: 43', 'clémentines :77', 'oranges : 30', 'pommes : 54']............how can i remove these "," and [] in the output – Isen Apr 14 '17 at 23:39
  • The brackets `[` and `]` are there because you are printing a list, from your comment it seems that you want to print the elements of said list... you need a loop for that. `for line in sorted(lecture): print(line) if line else continue` — the `''` in your output represent the empty lines that you HAVE in your file but the `print ... if line ...` takes care of that – gboffi Apr 15 '17 at 21:27
  • Ooops,the working incantation is `for line in sorted(lecture): print(line) if line else None` – gboffi Apr 15 '17 at 21:57
  • i will look at this tomorrow – Isen Apr 16 '17 at 03:41