I'm going back through Python Crash Course 2nd Edition for about the third time to cement my knowledge, & I've run into something interesting that I haven't actually accounted for in previous runs. When printing a lists length with the len() function, I realized I am not exactly sure how to perform this on a new line in this situation, so I added a separate print function above it that begins a new line itself. This causes the next line to be pushed down yet another line, as I'm assuming the line that is supposed to have my length on it, doesn't want to take its place where the previous print function already is, making 2 spacer lines. Is there a specific way I can print the length of this list on a new line without utilizing a separate print function?
I apologize if this seems silly. My code is as follows:
# -- Temporarily sort a list in alphabetical order -- #
colleges = ['Suffolk', 'Westbury', 'Maritime']
print("\nHere is the original list:")
print(*colleges, sep=', ')
print("\nHere is the temporarily sorted list:")
print(*sorted(colleges), sep=', ')
print("\nHere is the original list again:")
print(*colleges, sep=', ')
# -- Sorts list in reverse order, not alphabetically -- #
print("\nHere is a reversed list, not in alphabetical order:")
colleges.reverse()
print(*colleges, sep=', ')
# -- Printing the length of the list -- #
print("\n")
print(len(colleges))
I appreciate any help! These fundamentals are important to me.
The print() function automatically ends with a newline character (\n).
Then
print("\n")
print(len(colleges))
Equals
\n\nlen(colleges)\n
To achieve what you need you can make use of the extra arguments of print(). Like so:
print('\n', len(colleges))
Is there a specific way I can print the length of this list on a new line without utilizing a separate print function?
Omitting the print function preceding print(len(colleges)) will do the job.
The preceding print("\n") will print a new line, and end with a newline, hence the 2-line spacer.
See https://docs.python.org/3/library/functions.html#print - all print statements end with a newline by default.
You don't need the \n function. The len function automatically does this for you.
The reason why it does this is because all print statements automatically does this anyway.
Here is one solution:
# -- Printing the length of the list -- #
str = "\n" + str(len(colleges))
print(str)
Here is another:
# -- Printing the length of the list -- #
print()
print(len(colleges))
In general, any solution will involve changing this line somehow because it will always print two lines:
print("\n")
Related
I am very new to Python and am looking for assistance to where I am going wrong with an assignment. I have attempted different ways to approach the problem but keep getting stuck at the same point(s):
Problem 1: When I am trying to create a list of words from a file, I keep making a list for the words per line rather than the entire file
Problem 2: When I try and combine the lists I keep receiving "None" for my result or Nonetype errors [which I think means I have added the None's together(?)].
The assignment is:
#8.4 Open the file romeo.txt and read it line by line. For each line, split the line into a list of words using the split() method. The program should build a list of words. For each word on each line check to see if the word is already in the list and if not append it to the list. When the program completes, sort and print the resulting words in alphabetical order.You can download the sample data at http://www.py4e.com/code3/romeo.txt
My current code which is giving me a Nonetype error is:
poem = input("enter file:")
play = open(poem)
lst= list()
for line in play:
line=line.rstrip()
word=line.split()
if not word in lst:
lst= lst.append(word)
print(lst.sort())
If someone could just talk me through where I am going wrong that will be greatly appreciated!
your problem was lst= lst.append(word) this returns None
with open(poem) as f:
lines = f.read().split('\n') #you can also you readlines()
lst = []
for line in lines:
words = line.split()
for word in words:
if word:
lst.append(word)
Problem 1: When I am trying to create a list of words from a file, I keep making a list for the words per line rather than the entire file
You are doing play = open(poem) then for line in play: which is method for processing file line-by-line, if you want to process whole content at once then do:
play = open(poem)
content = play.read()
words = content.split()
Please always remember to close file after you used it i.e. do
play.close()
unless you use context manager way (i.e. like with open(poem) as f:)
Just to help you get into Python a little more:
You can:
1. Read whole file at once (if it is big it is better to grab it into RAM if you have enough of it, if not grab as much as you can for the chunk to be reasonable, then grab another one and so on)
2. Split data you read into words and
3. Use set() or dict() to remove duplicates
Along the way, you shouldn't forget to pay attention to upper and lower cases,
if you need same words, not just different not repeating strings
This will work in Py2 and Py3 as long as you do something about input() function in Py2 or use quotes when entering the path, so:
path = input("Filename: ")
f = open(filename)
c = f.read()
f.close()
words = set(x.lower() for x in c.split()) # This will make a set of lower case words, with no repetitions
# This equals to:
#words = set()
#for x in c.split():
# words.add(x.lower())
# set() is an unordered datatype ignoring duplicate items
# and it mimics mathematical sets and their properties (unions, intersections, ...)
# it is also fast as hell.
# Checking a list() each time for existance of the word is slow as hell
#----
# OK, you need a sorted list, so:
words = sorted(words)
# Or step-by-step:
#words = list(words)
#words.sort()
# Now words is your list
As for your errors, do not worry, they are common at the beginning in almost any objective oriented language.
Other explained them well in their comments. But not to make the answer lacking...:
Always pay attention on functions or methods which operate on the datatype (in place sort - list.sort(), list.append(), list.insert(), set.add()...) and which ones return a new version of the datatype (sorted(), str.lower()...).
If you ran into a similar situation again, use help() in interactive shell to see what exactly a function you used does.
>>> help(list.append)
>>> help(list.sort)
>>> help(str.lower)
>>> # Or any short documentation you need
Python, especially Python 3.x is sensitive to trying operations between types, but some might have a different connotation and can actually work while doing unexpected stuff.
E.g. you can do:
print(40*"x")
It will print out 40 'x' characters, because it will create a string of 40 characters.
But:
print([1, 2, 3]+None)
will, logically not work, which is what is happening somewhere in the rest of your code.
In some languages like javascript (terrible stuff) this will work perfectly well:
v = "abc "+123+" def";
Inserting the 123 seamlessly into the string. Which is usefull, but a programming nightmare and nonsense from another viewing angle.
Also, in Py3 a reasonable assumption from Py2 that you can mix unicode and byte strings and that automatic cast will be performed is not holding.
I.e. this is a TypeError:
print(b"abc"+"def")
because b"abc" is bytes() and "def" (or u"def") is str() in Py3 - what is unicode() in Py2)
Enjoy Python, it is the best!
So, I was studying basic things about Python. I encountered print function that basically prints something.
I learned that I could use [end=""] to end the print function.
For example,
my_job = 'hacker'
print(my_job, end="")
Basically gives me,
hacker
Another example, using the same values as above,
print(my_job, end="test")
Basically gives me,
hackertest
However, I then saw a cool thread in this site about how does the [end=""] function really works. I then noticed #Ritesh Karwa post this code,
myjob = 'hacker'
for c in myjob: print(c, end=" ")
Basically gave him,
h a c k e r
I know that the space inside the "" in the [end=] allowed the output to have spaces, but just how did that work? I mean, removing the [for c in myjob:] and only using the print function, the output became,
hacker
What is the mechanism behind this [for c in myjob:] that allowed the [end=] to apply spaces in between of the letters, resulting into this output,
h a c k e r
I wanted to ask #Ritesh Karwa directly through comments, but I don't have enough reputation. I'm not confident that I asked my question clearly, but I did my best. Thank you in advance for the helpful answers. I'm also using Python 3.xx
In Python, strings are also iterators (i.e. you can create a loop that will access them character by character). In this case:
for c in myjob:
is creating a loop where c will in turn have the value of each individual character in myjob.
If you then just did print(c) in the loop you would end up with
h
a
c
k
e
r
What the end=' ' is doing is replacing the default \n (newline) character that would normally force each print statement to print on a separate line as above and instead printing the contents of end=' ' (i.e. a space) after each print. That's giving you
h a c k e r
One thing you often have to remember after using end= is that the next print (which may be completely unrelated) will resume directly after the previous print, so would appear on the same line. People often would use a separate print() to print a newline so the next, unrelated print statement starts on a new line.
myjob is a string object, therefore an iterable. That means, that you can for example apply for loops such as for letter in myjob to iterate over all letters in the string.
As you have seen the optional end parameter of print replaces the standard end, which is a new line character with the one specified. So in this case, each occurrence in your for loop, the next letter is printed followed by a space. If you don't specify an end you will see that each letter would be printed to a new line.
end=“” removes the invisible new line (\n) that gets added at the end of a printing action.
Useful for for loops if you don’t want to get your results on separate lines.
I have a file which currently stores a string eeb39d3e-dd4f-11e8-acf7-a6389e8e7978
which I am trying to pass into as a variable to my subprocess command.
My current code looks like this
with open(logfilnavn, 'r') as t:
test = t.readlines()
print(test)
But this prints ['eeb39d3e-dd4f-11e8-acf7-a6389e8e7978\n'] and I don't want the part with ['\n'] to be passed into my command, so i'm trying to remove them by using replace.
with open(logfilnavn, 'r') as t:
test = t.readlines()
removestrings = test.replace('[', '').replace('[', '').replace('\\', '').replace("'", '').replace('n', '')
print(removestrings)
I get an exception value saying this so how can I replace these with nothing and store them as a string for my subprocess command?
'list' object has no attribute 'replace'
so how can I replace these with nothing and store them as a string for my subprocess command?
readline() returns a list. Try print(test[0].strip())
You can read the whole file and split lines using str.splitlines:
test = t.read().splitlines()
Your test variable is a list, because readlines() returns a list of all lines read.
Since you said the file only contains this one line, you probably wish to perform the replace on only the first line that you read:
removestrings = test[0].replace('[', '').replace('[', '').replace('\\', '').replace("'", '').replace('n', '')
Where you went wrong...
file.readlines() in python returns an array (collection or grouping of the same variable type) of the lines in the file -- arrays in python are called lists. you, here are treating the list as a string. you must first target the string inside it, then apply that string-only function.
In this case however, this would not work as you are trying to change the way the python interpretter has displayed it for one to understand.
Further information...
In code it would not be a string - we just can't easily understand the stack, heap and memory addresses easily. The example below would work for any number of lines (but it will only print the first element) you will need to change that and
this may be useful...
you could perhaps make the variables globally available (so that other parts of the program can read them
more useless stuff
before they go out of scope - the word used to mean the points at which the interpreter (what runs the program) believes the variable is useful - so that it can remove it from memory, or in much larger programs only worry about the locality of variables e.g. when using for loops i is used a lot without scope there would need to be a different name for each variable in the whole project. scopes however get specialised (meaning that if a scope contains the re-declaration of a variable this would fail as it is already seen as being one. an easy way to understand this might be to think of them being branches and the connections between the tips of branches. they don't touch along with their variables.
solution?
e.g:
with open(logfilenavn, 'r') as file:
lines = file.readlines() # creates a list
# an in-line for loop that goes through each item and takes off the last character: \n - the newline character
#this will work with any number of lines
strippedLines = [line[:-1] for line in lines]
#or
strippedLines = [line.replace('\n', '') for line in lines]
#you can now print the string stored within the list
print(strippedLines[0]) # this prints the first element in the list
I hope this helped!
You get the error because readlines returns a list object. Since you mentioned in the comment that there is just one line in the file, its better to use readline() instead,
line = "" # so you can use it as a variable outside `with` scope,
with open("logfilnavn", 'r') as t:
line = t.readline()
print(line)
# output,
eeb39d3e-dd4f-11e8-acf7-a6389e8e7978
readlines will return a list of lines, and you can't use replace with a list.
If you really want to use readlines, you should know that it doesn't remove the newline character from the end, you'll have to do it yourself.
lines = [line.rstrip('\n') for line in t.readlines()]
But still, after removing the newline character yourself from the end of each line, you'll have a list of lines. And from the question, it looks like, you only have one line, you can just access first line lines[0].
Or you can just leave out readlines, and just use read, it'll read all of the contents from the file. And then just do rstrip.
contents = t.read().rstrip('\n')
As a challenge in 'efficiency' (rather, compactness of code, and certainly not pythonicness of code) I've been tasked to write code on a single line that will return a valid formula for the sequence, given the input will be a valid integer sequence separated by ", ". This is what I have:
for b in input(">>> ").split(", "): print("(((((",b,"-n)/(",b,"-n))+1)%2)*",b,")+",sep="",end="")
However, there are problems with this. The only real problem I'm concerned with is how to NOT print a "+" at the final item of the list (as it won't be added to anything). I was hoping there'd be a way with list comprehension but I can't think of one. Is this possible? If so, can I even add in error handling, that ignores items of the input list that aren't valid integers? (By the way, the maths works out. I think.)
you can use join to contact item together
"+".join( "((((({}-n)/({}-n))+1)%2)*{})".format(*([item]*3)) for item in input(">>> ").split(", ") )
example:
"+".join( "((((({}-n)/({}-n))+1)%2)*{})".format(*([item]*3)) for item in [1,2,3,4] )
'(((((1-n)/(1-n))+1)%2)*1)+(((((2-n)/(2-n))+1)%2)*2)+(((((3-n)/(3-n))+1)%2)*3)+(((((4-n)/(4-n))+1)%2)*4)'
I'm trying to find common elements in the strings reading from a file. And this is what I wrote:
file = open ("words.txt", 'r')
while 1:
line = file.readlines()
if len(line) == 0:
break
print line
file.close
def com_Letters(*strings):
return set.intersection(*map(set,strings))
and the result turns out: ['out\n', 'dog\n', 'pingo\n', 'coconut']
I put com_Letters(line), but the result is empty.
There are two problems, but neither one is with com_Letters.
First, this code guarantees that line will always be an empty list:
while 1:
line = file.readlines()
if len(line) == 0:
break
print line
The first time through the loop, you call readlines(), which will
Read until EOF using readline() and return a list containing the lines thus read.
If the file is empty, that's an empty list, so you'll break.
Otherwise, you'll print out the list, and go back into the loop. At which point readlines() is going to have nothing left to read, since you already read until EOF, so it's guaranteed to be an empty list. Which means you'll break.
Either way, list ends up empty.
It's not clear what you're trying to do with that loop. There's never any good reason to call readlines() repeatedly on the same file. But, even if there were, you'd probably want to accumulate all of the results, rather than just keeping the last (guaranteed-empty) result. Something like this:
while 1:
new_line = file.readlines()
if len(new_line) == 0:
break
print new_line
line += new_line
Anyway, if you fix that problem (e.g., by scrapping the whole loop and just using line = file.readlines()), you're calling com_Letters with a single list of strings. That's not particularly useful; it's just a very convoluted way of calling set. If it's not clear why:
Since there's only one argument (a list of strings), *strings ends up as a one-element tuple of that argument.
map(set, strings) on a single-element tuple just calls set on that element and returns a single-element list.
*map(set, strings) explodes that into one argument, the set.
set.intersection(s) is the same thing as s.intersection(), which just returns s itself.
All of this would be easier to see if you broke up some of those complex expressions and printed the intermediate values. Then you'd know exactly where it first goes wrong, instead of just knowing it's somewhere in a long chain of events.
A few side notes:
You forgot the () on the file.close, which means you're not actually closing the file. One of the many reasons that with is better is that it means you can't make that mistake.
Use plural names for collections. line sounds like a variable that should have a single line in it, not a variable that should have all of your lines.
The readlines function with no sizehint argument is basically useless. If you're just going to iterate over the lines, you can do that to the file itself. If you really need the lines in a list instead of reading them lazily, list(file) makes your intention clearer—and doesn't mislead you into thinking it might be useful to do repeatedly.
The Pythonic way to check for an empty collection is just if not line:, rather than if len(line) == 0:.
while True is clearer than while 1.
I suggest modifying the function as follows:
def com_Letters(strings):
return set.intersection(*map(set,strings))
I think the function is treating the argument strings as a list of a list of strings (only one argument passed in this case a single list) and therefore not finding the intersection.