Eliminazione di una riga da un file in Python

Sto cercando di eliminare una riga che contiene una stringa specifica.

Ho un file chiamato numbers.txt con il seguente contenuto:

pietro

tom

tom1

yan

Quello che voglio eliminare è che tom dal file, quindi ho fatto questa funzione:

def deleteLine():
fn = 'numbers.txt'
f = open(fn)
output = []
for line in f:
    if not "tom" in line:
        output.append(line)
f.close()
f = open(fn, 'w')
f.writelines(output)
f.close()

L’output è:

pietro

yan

Come si può vedere, il problema è che la funzione di eliminare tom e tom1, ma non voglio eliminare tom1. Voglio eliminare solo tom. Questo è il risultato che vorrei avere:

pietro

tom1

yan

Idee per modificare la funzione per fare questo correttamente?

InformationsquelleAutor Borja | 2011-05-10



5 Replies
  1. 12

    modificare la riga:

        if not "tom" in line:

    a:

        if "tom" != line.strip():
    • Non c’è bisogno di eliminare una linea iterato da un fileobj.
    • Python 2.5.4 su Mac non striscia di nuove linee di caratteri durante l’iterazione di un fileobj, quindi, se si desidera confrontare una stringa, è necessario rimuoverlo. Anche io ho visto molti bug dopo uno spazio, in qualche modo, è riuscita ad intrufolarsi alla fine della linea e il codice non gestire.
    • Come molto strano, win e linux sembra striscia senza denuncia, grazie per avermi insegnato qualcosa 🙂
    • Bowyer: Per completezza, che non è vero. Le linee non sono spogliato in linux o windows. Tutte le linee leggere da un file oggetto in python venire con un ritorno a capo, a prescindere dalla piattaforma
    • Mi dispiace D: ho appena stampato repr della linea e realizzato un vostro diritto…
  2. 4

    Perché

    if not "tom" in line

    controlli, se tom non è una sottostringa di corrente line. Ma in tom1, tom è una sottostringa. Quindi, questo viene eliminato.

    Probabilmente si potrebbe desiderare di uno dei seguenti:

    if not "tom\n"==line # checks for complete (un)identity
    if "tom\n" != line # checks for complete (un)identity, classical way
    if not "tom"==line.strip() # first removes surrounding whitespace from `line`
    • Non è davvero una soluzione?
    • Bowyer: Aggiunto.
    • Non c’è bisogno di eliminare una riga durante l’iterazione direttamente su un fileobj, si dovrebbe, invece, si spogliato le stringhe già.
    • Bowyer: No, questo è sbagliato. Si non bisogno di striscia la linea quando l’iterazione su un fileobj. Darà le linee di con un ritorno a capo quindi, se non si striscia il stringhe non uguali.
    • Mi dispiace D: ho appena stampato repr della linea e realizzato un vostro diritto…
  3. 3

    Solo per divertimento, ecco un due-liner per farlo.

    lines = filter(lambda x:x[0:-1]!="tom", open("names.txt", "r"))
    open("names.txt", "w").write("".join(lines))

    Sfida: qualcuno posta un one-liner per questo.

    Si potrebbe anche usare il fileinput modulo per ottenere probabilmente il più significativo risultato:

    import fileinput
    for l in fileinput.input("names.txt", inplace=1):
        if l != "tom\n": print l[:-1]
    • open("names_out.txt", "w").write("\n".join(line for line in open("names.txt", "r") if line[:-1] != "tom")). Credo che non funziona se i due nomi di file sono identici, però.
    • Whoops. Dovrebbe essere "".join invece di "\n".join sopra. E credo che il posto di trasformazione può essere ottenuto anche con il fileinput modulo.
    • Qualcosa di simile subprocess.Popen("sed -i '' -e'/^tom$/d' numbers.txt") forse?
  4. 1

    È possibile utilizzare regex.

    import re
    if not re.match("^tom$", line):
        output.append(line)

    Il $ significa la fine della stringa.

    • Se si va giù che il percorso è inoltre necessario corrispondere l’inizio della stringa, cioè, re.match("^tom$", line).
    • hai ragione.
    • Se ha ragione, quindi modificare la tua risposta 🙂
    • Risolto.
    • si ma non per questo meno colpevoli di fissaggio di riza.
    • sei colpevole di errore di presunzioni. i mai creduto che deve essere modificato, dato che ha usato .match e non .search; la mia affermazione era un semplice “se-allora” nudge in risposta a riza commenti e non la modifica.

  5. 0

    Sono nuovo nella programmazione e python (un paio di mesi)… questa è la mia soluzione:

    import fileinput
    
    c = 0 # counter
    for line in fileinput.input("korrer.csv", inplace=True, mode="rb"):
        # the line I want to delete
        if c == 3: 
            c += 1
            pass
        else:
            line = line.replace("\n", "")
            print line
            c +=1

    Sono sicuro che c’è un modo più semplice, solo un’idea. (il mio inglese non è molto buono!!)

Lascia un commento