22324

Search a single column for a particular value in a CSV file and return an entire row

<strong>Issue</strong>

The code does not correctly identify the input (item). It simply dumps to my failure message even if such a value exists in the CSV file. Can anyone help me determine what I am doing wrong?

<strong>Background</strong>

I am working on a small program that asks for user input (function not given here), searches a specific column in a CSV file (Item) and returns the entire row. The CSV data format is shown below. I have shortened the data from the actual amount (49 field names, 18000+ rows).

Code

import csv from collections import namedtuple from contextlib import closing def search(): item = 1000001 raw_data = 'active_sanitized.csv' failure = 'No matching item could be found with that item code. Please try again.' check = False with closing(open(raw_data, newline='')) as open_data: read_data = csv.DictReader(open_data, delimiter=';') item_data = namedtuple('item_data', read_data.fieldnames) while check == False: for row in map(item_data._make, read_data): if row.Item == item: return row else: return failure

CSV structure

active_sanitized.csv Item;Name;Cost;Qty;Price;Description 1000001;Name here:1;1001;1;11;Item description here:1 1000002;Name here:2;1002;2;22;Item description here:2 1000003;Name here:3;1003;3;33;Item description here:3 1000004;Name here:4;1004;4;44;Item description here:4 1000005;Name here:5;1005;5;55;Item description here:5 1000006;Name here:6;1006;6;66;Item description here:6 1000007;Name here:7;1007;7;77;Item description here:7 1000008;Name here:8;1008;8;88;Item description here:8 1000009;Name here:9;1009;9;99;Item description here:9

<strong>Notes</strong>

My experience with Python is relatively little, but I thought this would be a good problem to start with in order to learn more.

I determined the methods to open (and wrap in a close function) the CSV file, read the data via DictReader (to get the field names), and then create a named tuple to be able to quickly select the desired columns for the output (Item, Cost, Price, Name). Column order is important, hence the use of DictReader and namedtuple.

While there is the possibility of hard-coding each of the field names, I felt that if the program can read them on file open, it would be much more helpful when working on similar files that have the same column names but different column organization.

<strong>Research</strong>

    <li>CSV Header and named tuple: What is the pythonic way to read CSV file data as rows of namedtuples?</li> <li>Converting CSV data to tuple: How to split a CSV row so row[0] is the name and any remaining items are a tuple?</li> <li>There were additional links of research, but I cannot post more than two.</li> </ul>

    Answer1:

    You have three problems with this:

      <li>You return on the first failure, so it will never get past the first line.</li> <li>You are reading strings from the file, and comparing to an int.</li> <li>

      _make iterates over the dictionary keys, not the values, producing the wrong result (item_data(Item='Name', Name='Price', Cost='Qty', Qty='Item', Price='Cost', Description='Description')).

      for row in (item_data(**data) for data in read_data): if row.Item == str(item): return row return failure </li> </ul>

      This fixes the issues at hand - we check against a string, and we only return if none of the items matched (although you might want to begin converting the strings to ints in the data rather than this hackish fix for the string/int issue).

      I have also changed the way you are looping - using a generator expression makes for a more natural syntax, using the normal construction syntax for named attributes from a dict. This is cleaner and more readable than using _make and map(). It also fixes problem 3.

Recommend

  • In python 2.7 - How to read data from csv, reformat data, and write to new csv
  • Input multiple files in python using * via the command line
  • How to address: Python import of file with .csv Dictreader fails on undefined character
  • Communication b/w two threads over a common datastructure. Design Issue
  • Python unicode equal comparison failed in terminal but working under Spyder editor
  • Reading a file of lists of integers in Fortran
  • Script Python using plone.api to create File appear error WrongType when set a file
  • How to use float ** in Python with Swig?
  • Standard way for writing a debug mode in C++
  • Complex python3 csv scraper
  • windows batch file combine csv in a folder by column
  • Plot a CSV file where the delimiter is '; ' (semicolon + space)
  • CSV and MS-DOS CSV Formats
  • ValueError: Found arrays with inconsistent numbers of samples
  • How to remove comma or any characters from Python dataframe column name
  • SSH in Bash Script Messing Up File Read
  • Dependable views in Ember
  • Regex for Specific Tag
  • Avoid registering duplicate broadcast receivers in Android
  • Java making confirming exit
  • SAXReader not re-ecape characters
  • Not able to aggregate on nested fields in elasticsearch
  • Textfile Structure (tables)
  • Swift: Switch statement fallthrough behavior
  • How to avoid particles glitching together in an elastic particle collision simulator?
  • Recording logins for password protected directories
  • Disabling Alt-F4 on a Win Forms NotifyIcon
  • Splitting given String into two variables - php
  • How to redirect a user to a different server and include HTTP basic authentication credentials?
  • Check if a string to interpolate provides expected placeholders
  • Can I make an Android app that runs a web view in Chrome 39?
  • 0x202A in filename: Why?
  • What are the advantages and disadvantages of reading an entire file into a single String as opposed
  • LevelDB C iterator
  • Linking SubReports Without LinkChild/LinkMaster
  • Bitwise OR returns boolean when one of operands is nil
  • Can't mass-assign protected attributes when import data from csv file
  • sending mail using smtp is too slow
  • costura.fody for a dll that references another dll
  • Binding checkboxes to object values in AngularJs