In questa sezione descriviamo come specificare il formato con cui stampare le informazioni sia sullo shermo che in un file.
La funzione print
è il comando utilizzato più comunemente per stampare informazioni sullo “standard output device” che normalmente è lo schermo.
Ci sono due modi per usare print.
Il modo più facile di usare il comando print
è passargli l'elenco delle variabili da stampare separate da un virgola. Qualche esempio:
a = 10
b = 'test text'
print(a)
print(b)
print(a, b)
print("The answer is", a)
print("The answer is", a, "and the string contains", b)
Python aggiunge uno spazio tra ogni coppia di oggetti che viene stampata.
Python va a capo dopo ogni chiamata a print. Per impedirlo, usate il parametro end=
:
# Comportamento di default
print("Printing in line one")
print("...still printing in line one (just kidding).")
# sostituendo il simbolo di 'a capo' (\n) con uno spazio nel primo statement'
print("Printing in line one",end=" ")
print("...still printing in line one (now it works).")
Un sistema built-in di formattazione permette una grande flessibilità.
Le idee fondamentali attraverso esempi:
"{} needs {} pints".format('Peter',4) # inserire i valori nell'ordine in cui devono comparire
"{0} needs {1} pints".format('Peter', 4) # specificare l'indice dell'elemento
"{1} needs {0} pints".format('Peter', 4)
"{name} needs {number} pints".format( # specificare il nome dell'elemento da
name='Peter',number=4) # stampare
import math
"Pi is approximately {:f}.".format(math.pi) # si può spcificare il format per i reali.
# Notate che il format è introdotto da ":"
# all'interno della parentesi graffa
Una specificazione di formato del tipo W.Df
significa che il numero reale deve essere stampato con una lunghezza totale di W
caratteri e D
cifre dopo il punto decimale.
"Pi is approximately {:.2f}.".format(math.pi) # si può specificare il numero di cifre dopo la virgola
"Pi is approximately {:6.2f}.".format(math.pi) # e la lunghezza totale
Un esempio di come mescolare formati e ordine delle variabili:
"{1:10.8f} --- {0:7.3e} pints".format(3*math.pi, math.pi)
È sufficiente mettere il simbolo f
, da cui il nome f-strings, di fronte al delimitatore iniziale della stringa e poi, all'interno della stringa stessa specificare variabile e formato fra parentesi graffe.
my_a = math.pi
print(f"a = {my_a:7.4f}")
print(f"2*Pi is approximately {2*math.pi:4.2f}.")
Una lista dei formati comunemente usati usando l'unità astronomica (distanza media Sole-Terra in metri): AU = 149597870700 m.
specifier | style | Example output for AU |
---|---|---|
f |
floating point | 149597870700.000000 |
e |
exponential notation | 1.495979e+11 |
g |
shorter of %e or %f | 1.49598e+11 |
d |
integer | 149597870700 |
x |
exadecimal | 22d4ba5a6c |
o |
octal | 2132456455154 |
s |
str() |
149597870700 |
AU = 149597870700 # unità astronomica [m]
AU_f = f"{AU:f}" # la prima linee della tavola
AU_f
AU_f1 = f"{AU:.1f}" # la prima linee della tavola con una sola cifra dopo il punto
AU_f1
AU_e = f"{AU:e}" # la seconda linee della tavola. Il formato esponenziale ha una cifra prima del punto.
AU_e
AU_e4 = f"{AU:.4e}" # la seconda linee della tavola con quattro cifre dopo il punto
AU_e4
Il simbolo >, <, ^ allinea le variabili a destra, sinistra, centro dello spazio disponibile. L'allineamento a destra è il default per le variabili numeriche; l'allineamento a sinistra è il default per quasi tutte gli altri tipi di variabili.
Table = [[1,2,3],[5,6,7],[8,9,10]]
info = ["dato 1","dato 2","dato 3"]
print(f"{info[0]:>8s} {info[1]:>8s} {info[2]:>8s}")
print(30*'-')
for i in range(len(Table)):
print(f"{Table[i][0]:8d} {Table[i][1]:8d} {Table[i][2]:8d}")
# print(f"{Table[i][0]:i8} {Table[i][1]:i8} {Table[i][2]:i8}")
dato 1 dato 2 dato 3 ------------------------------ 1 2 3 5 6 7 8 9 10
Separando più chiaramente le colonne
Table = [[1,2,3],[5,6,7],[8,9,10]]
info = ["dato 1","dato 2","dato 3"]
print(34*'-')
print(f"| {info[0]:>8s} | {info[1]:>8s} | {info[2]:>8s} |")
print(34*'-')
for i in range(len(Table)):
print(f"| {Table[i][0]:8d} | {Table[i][1]:8d} | {Table[i][2]:8d} |")
print(34*'-')
---------------------------------- | dato 1 | dato 2 | dato 3 | ---------------------------------- | 1 | 2 | 3 | | 5 | 6 | 7 | | 8 | 9 | 10 | ----------------------------------
Effetto di allineamenti diversi:
Table = [[1,2,3],[5,6,7],[8,9,10]]
info = ["dato 1","dato 2","dato 3"]
print(34*'-')
print(f"| {info[0]:8s} | {info[1]:^8s} | {info[2]:>8s} |")
print(34*'-')
for i in range(len(Table)):
print(f"| {Table[i][0]:^8d} | {Table[i][1]:<8d} | {Table[i][2]:8d} |")
print(34*'-')
# print(f"{Table[i][0]:i8} {Table[i][1]:i8} {Table[i][2]:i8}")
---------------------------------- | dato 1 | dato 2 | dato 3 | ---------------------------------- | 1 | 2 | 3 | | 5 | 6 | 7 | | 8 | 9 | 10 | ----------------------------------
Come incolonnare numeri reali e interi richiedendo lo stesso numero di cifre dopo il punto di separazione:
Table = [[1.2,2,3.14],[-5.0,6.17,7],[8,9,10]]
info = ["dato 1","dato 2","dato3"]
print(f"{info[0]:>12s} {info[1]:>12s} {info[1]:>12s}")
print(42*'-')
for i in range(len(Table)):
print(f"{Table[i][0]:12.2f} {Table[i][1]:12.2f} {Table[i][2]:12.2f}")
# print(f"{Table[i][0]:i8} {Table[i][1]:i8} {Table[i][2]:i8}")
dato 1 dato 2 dato 2 ------------------------------------------ 1.20 2.00 3.14 -5.00 6.17 7.00 8.00 9.00 10.00
Ecco un programmma che
crea un file di nome test.txt
,
scrive del testo nel file,
chiude il file.
I dati che vengono immagazzinati nel file test.txt
sono:
Writing text to file. This is the first line.
And the second line.
Third line!!!!!!!
# 1. Scrivere in un file
out_file = open("test.txt", "w") # Il file viene aperto/creato in scrittura.
# 'w' vuol dire write.
out_file.write("Writing text to file. This is the first line.\n"+\
"And the second line.\n Third line!!!!!!!")
# Il singolo carattere "\n" segnala la fine di una riga. Vuol dire "a capo".
out_file.close() # chiude il file
La cella seguente
apre il file di nome test.txt
,
legge il testo dal file,
stampa il testo sullo schermo.
chiude il file
# 2. Leggere dal file
in_file = open("test.txt", "r") # Il file viene aperto in lettura. 'r' vuol dire read.
text = in_file.read() # Legge tutto il file in una variabile "text" di
# tipo stringa
in_file.close() # chiude il file
# 3. Mostrare i dati
print(text)
Più in dettaglio, il file viene aperto con il comando open
. L'oggetto file aperto viene assegnato alla variabile out_file
. Il testo viene scritto nel file usando il metodo out_file.write
. Si noti che nell'esempio più sopra, al metodo write
è stata passata una stringa. Si possono usare, ovviamente, tutte specificazioni di formato discusse in precedenza — si veda formatted printing e new style formatting. È buona pratica usare close()
su tutti i files in cui si è finito di leggere e scrivere. Se un programma Python finisce in modo controllato (cioè non per una caduta di tensione o un improbabile bug del linguaggio o del sistema operativo) tutti i files aperti vengono chiusi non appena i file objects vengono distrutti. Tuttavia, chiuderli esplicitamente non appena possibile è uno stile migliore di programmazione.
Creiamo un file chiamato myfile.txt
che contiene le tre linee di testo seguenti:
This is the first line.
This is the second line.
This is a third and last line.
Il metodo write non aggiunge il carattere newline (\n)
alla fine di ogni operazione di scrittura
f = open('myfile.txt', 'w')
f.write('This is the first line.\n'
'This is the second line.\n'
'This is the third and last line.')
f.close()
Modi equivalenti:
f1 = open('myfile1.txt', 'w')
f1.write('This is the first line.\n''This is the second line.\n''This is the third and last line.')
f1.close()
f2 = open('myfile2.txt', 'w')
f2.write('This is the first line.\n'+'This is the second line.\n'+'This is the third and last line.')
f2.close()
È sbagliato passare a write
più stringhe separate da virgole. write
accetta un solo argomento.
f3 = open('myfile3.txt', 'w')
f3.write('This is the first line.\n','This is the second line.\n','This is the third and last line.')
f3.close()
Il metodo fileobject.read()
legge tutto il file, e lo restituisce come una singola stringa (inclusi i caratteri di "a capo" \n
).
f = open('myfile.txt', 'r')
f.read()
f.close()
Il metodo fileobject.readlines()
restituisce una lista di stringhe, in cui ciascun elemento della lista corrisponde a una linea del file:
f = open('myfile.txt', 'r')
f.readlines()
f.close()
Questo metodo viene spesso utilizzato per iterare sulle linee, compiendo delle operzioni su ciascuna linea. Per esempio:
f = open('myfile.txt', 'r')
for line in f.readlines():
print(f"{len(line)} characters")
f.close()
Si noti che readlines()
immagazzina tutto il file in una lista di stringhe. Non è un problema se si è sicuri che il file è piccolo e che può essere contenuto nella memoria disponibile.
In questo caso, possiamo chiudere il file prima di processarne il contenuto:
f = open('myfile.txt', 'r')
lines = f.readlines()
f.close()
for line in lines:
print("%d characters %s" % (len(line),line))
lines
Esiste una notazione ancora più semplice per leggere un file linea per linea che (1) legge solo una linea alla volta (e quindi è adatto anche a files grandi) e (2) produce un codice più compatto:
f = open('myfile.txt', 'r')
for line in f:
print(f"{len(line)} characters")
f.close()
In questo caso, il "file handle" f
agisce come un iteratore e restituisce la linea seguente a ogni iterazione del for-loop fino alla fine del file (quando il for-loop finisce). In alternativa si può usare il metodo readline
che restituisce una riga alla volta:
f = open('myfile.txt', 'r')
l1 = f.readline()
print(l1)
l2 = f.readline()
print(l2)
f.close()
with
¶La documentazione di Python consiglia accedere ai file con la keyword with
:
with open('myfile.txt') as f:
for line in f:
print(f"{len(line)} characters")
Questa notazione chiude automaticamente il file alla fine delle operazioni contenute nel blocco with
anche se il programma si fermasse per un errore. Il comando close
non è più necessario.
La directory di lavoro si trova con il comando (magico)
%pwd
Aprire un file già esistente utilizzando il path assoluto
with open(r"/Users/maina/cernbox/python/MyCourse/path_test_dir/pippo1.txt") as filein:
for line in filein:
print(f"{line} :: {len(line)} characters")
Creare un nuovo file utilizzando il path assoluto e passando il parametro "w"
al comando open
lines = ["pippo", "pluto", "non c'è trippa per gatti"]
with open(r"/Users/maina/cernbox/python/MyCourse/path_test_dir/pippo2.txt","w") as fileout:
for line in lines:
fileout.write(line+"\n")
Check:
test = open(r"/Users/maina/cernbox/python/MyCourse/path_test_dir/pippo2.txt")
res = test.read()
print(res)
res
Aprire un file già esistente utilizzando il path relativo
with open(r"../path_test_dir/pippo1.txt") as filein:
for line in filein:
print(f"{line} :: {len(line)} characters")
Notate come nelle celle precedenti il path venga passato in stringhe che hanno la lettera r
prima del delimitatore. Questo tipi di stringhe si chiamano raw strings
. Tutto il testo contenuto nella stringa viene scritto esattamente come appare, per esempio "\n" viene interpretato come backslash
+ n
e non come il simbolo di a capo
.
Partendo da due o più oggetti iterabili (stringhe, liste, ntuple) di uguale lunghezza restituisce un iteratore che combina
il contenuto degli oggetti di partenza.
Esempi:
l1 = [1,2,3]
l2 = ['a','b','c']
list(zip(l1,l2))
l1 = 'pippo'
l2 = 'pluto'
list(zip(l1,l2))
l1 = [1,2,3,4,5]
l2 = 'pluto'
list(zip(l1,l2))