Excel File Duplikate

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
SeriousRuffy
User
Beiträge: 32
Registriert: Dienstag 16. Dezember 2014, 21:16

Hallo zusammen,

Zunächst einmal wollte eine Excel File auf Duplikate überprüfen, welches ich auch erfolgreich geschafft habe. Das Programm spuckt quasi raus, wieviele Länder wie oft in der angegebenen Spalte vorkommen.

Code: Alles auswählen

import csv


lesdatei = open("Test_08_01_2015.csv", "r")
schreibdatei= open("Final.csv", "w")
Country = {}

reader = csv.reader(lesdatei, delimiter=';', quotechar="'")

rowNum = 0
for row in reader:
    rowNum += 1
    countryName = str(row[8]).strip()
    if countryName in Country:
        Country[countryName] += 1
    elif countryName.strip() != "":
            Country[countryName] = 1


for country in Country:
    if Country[country] > 1:

        print("Country Name: " + country + ": " + str(Country[country]))
        schreibdatei.write("Country Name: " + country + ": " + str(Country[country]) + "\n") #oder auch \r"\n"

print(rowNum)
schreibdatei.write("Number of Rows: " + str(rowNum)+"\n")
print(len(Country))
schreibdatei.write("Number of Country: " + str(len(Country))+"\n")
Outcome

Code: Alles auswählen

Country Name: Ghana: 2
Country Name: Detuschland: 2
17223
16469
Jetzt möchte ich zusätzlich, dass das Programm mir zusätzlich die nächste Spalte (in diesem Fall die Adresse) ausspuckt, aber allerdings nur die Werte(Adresse), die zu den Duplikaten gehören.

Mir ist klar, das ich in der neuen Schleife mein Orginaldatei wieder brauche, um die Adress Spalte einzulesen. Und soweit ich das verstanden habe, muss ich mir eine temporäre Variable bilden, damit das Programm mir die Countryname Duplikate und die dazugehörigen Adressen zurück liefert.

Allerings ist mir das Konzept von temporären Variablen nicht klar bzw. verstehe nicht, wie ich anwenden soll. Könnt Ihr mir Tipps geben? Danke für euer Feedback
BlackJack

@SeriousRuffy: Das würde man in *einem* Durchlauf erledigen in dem man in dem Wörterbuch nicht die Länder zählt, sondern die Länder auf Listen mit Adressen abbildet. Und bei jedem Land mit mehr als einer Adresse hat man ein Land das mehrfach vorkommt, und dann auch gleich die Adressen dazu. Statt eines `dict` bietet sich hier `collections.defaultdict` an um den Code einfacher zu machen. (Bei dem bisherigen Code wäre `collections.Counter` nützlich gewesen.)

Dateien die man öffnet, sollte man auch wieder schliessen. Hier bietet sich die ``with``-Anweisung an um das schliessen auch in Ausnahmefällen sicher zu stellen.

Deine Namensschreibweise hält sich nicht an den Style Guide for Python Code und ist teilweise verwirrend. Wie soll denn der Benutzer die Namen `country` und `Country` auseinanderhalten wenn eines für ein Land steht und das andere für eine Datenstruktur mit vielen Ländern. Einleuchtend ist das nicht, zumal `Country` die konventionelle Schreibweise für eine Klasse/einen Datentyp ist — selbst wenn man mixedCase-Namen verwendet.

Statt `rowNum` manuell hochzuzählen würde man `enumerate()` verwenden.

Der `str()`-Aufruf auf das Element aus `row` ist überflüssig, das ist bereits eine Zeichenkette.

Edit: Ungetestet:

Code: Alles auswählen

from __future__ import absolute_import, division, print_function
import csv
from collections import defaultdict

COUNTRY_NAME_COLUMN = 8
ADDRESS_COLUMN = 9


def main():
    with open('Test_08_01_2015.csv', 'r') as input_file:
        country2adresses = defaultdict(list)
        row_count = 0
        reader = csv.reader(input_file, delimiter=';', quotechar="'")
        for row_count, row in enumerate(reader, 1):
            country_name = row[COUNTRY_NAME_COLUMN].strip()
            if country_name:
                country2adresses[country_name].append(
                    row[ADDRESS_COLUMN].strip()
                )

    with open('Final.csv', 'w') as output_file:
        for country_name, addresses in sorted(country2adresses.iteritems()):
            if len(addresses) > 1:
                line = 'Country name: {0}:{1}:{2}\n'.format(
                    country_name, len(addresses), '; '.join(addresses)
                )
                print(line, end='')
                output_file.write(line)

        print(row_count)
        output_file.write('Number of rows: {0}\n'.format(row_count))
        print(len(country2adresses))
        output_file.write(
            'Number of countries: {0}\n'.format(len(country2adresses))
        )


if __name__ == '__main__':
    main()
SeriousRuffy
User
Beiträge: 32
Registriert: Dienstag 16. Dezember 2014, 21:16

Danke für dein ausführliches Feedback!!! Werde es beherzigen:)

Das einzige, was ich an dem Code geändert habe, ist das ich

Code: Alles auswählen

country2adresses.iteritems()
zu

Code: Alles auswählen

country2adresses.items()
gemacht habe, da ich Version 3 benutze.
Antworten