-2

I need to write a program in a functional way. I have a text and I need to calculate a number of unique words, (for example: "word word, word word?" - has 3 different words, punctuation matters.

I have a code:

import sys
import re
print(len(set(re.findall('[^ \n]+', sys.stdin.readline()))))

the problem is that i can read only one line this way, I tried to replace readline by read, but it not working.

L.Bond
  • 37
  • 6
  • 1
    What does "functional" mean for you in this context? – DYZ Mar 24 '18 at 22:23
  • "_but it not working_" - what exactly is not working? Can you show the error message? – DYZ Mar 24 '18 at 22:25
  • i need to use sys function, the problem that if i read using sys.stdin.readline() i can get the result for one row, if i am using read the program shows run time error – L.Bond Mar 24 '18 at 22:37
  • There is no `sys` function. `sys` is a module. Please include the complete error message in the question. – DYZ Mar 24 '18 at 22:39
  • I have a text:"She sells sea shells on the sea shore; The shells that she sells are sea shells I'm sure. So if she sells sea shells on the sea shore, I'm sure that the shells are sea shore shells." The correct output would be 19, if I am using readline the result is 7 which is correct. But i am not able to calculate the result for the whole text, the program is not showing any output – L.Bond Mar 24 '18 at 22:45
  • 1
    You will not get much help here if you refuse to follow our requests. – DYZ Mar 24 '18 at 22:46

2 Answers2

2

Python file objects are iterable. So we can apply the usual itertools mix to them. What you've done with one line can be easily extended to several.

print(list(map(lambda x: len(set(re.findall('[^ \n]+', x))), sys.stdin)))

As was mentioned in the other answer, I suggest using some intermediate variables to make this prettier (doing so does not affect how functional your code is, provided you never mutate the variables)

def handle_line(x):
    coll = set(re.findall('[^ \n]+', x))
    return len(coll)

result = map(handle_line, sys.stdin)
print(list(result))

If you want to run once for the whole file, rather than running a separate iteration on each line, you can get the whole file like so.

# Be careful; this will DEFINITELY fail on large files
file_data = '\n'.join(list(sys.stdin))

Then you can run your len(set(...)) sequence of operations on the resulting string instead.

Silvio Mayolo
  • 62,821
  • 6
  • 74
  • 116
  • Your code shows unique words per line, not for the whole file. – DYZ Mar 24 '18 at 22:26
  • Ah, does OP want it for the whole file at once? That was not how I understood the question, but I can see how I could be mistaken. – Silvio Mayolo Mar 24 '18 at 22:40
  • for example: "She sells sea shells on the sea shore; The shells that she sells are sea shells I'm sure. So if she sells sea shells on the sea shore, I'm sure that the shells are sea shore shells." the output should be 19, but i have only 7, only first line is taken into account – L.Bond Mar 24 '18 at 22:51
1

What about simply

text = "word word, word word?"
words = text.split()
unique_words = set(words)
nr_unique_words = len(unique_words)

Of course, this can be written mure succinctly:

print(len(set("word word, word word?".split())))
jmd_dk
  • 12,125
  • 9
  • 63
  • 94
  • I need to write in a "functional way" using sys – L.Bond Mar 24 '18 at 22:05
  • 1
    @L.Bond That's an odd use of the term "functional". What exactly are your requirements? If it's just about where the text is coming from, that has nothing to do with how you process it. – Patrick Haugh Mar 24 '18 at 22:06
  • 1
    I'm not sure what you mean by "functional" in this regard. You can't just put a loop in and do this for every line of the file? – jmd_dk Mar 24 '18 at 22:07