1

I've seen a lot of posts about doing this backwards, but I haven't been able to find any way to write the contents of a column in a csv file to a list. After I have this I'll loop through to add all of the unique value to a separate list and count the number of total unique values. This is what I have:

b=[]
c=[]
servers = []
fname=(r'file')
with open(fname, 'r') as f:
    reader = csv.reader(f)
    severities = Counter(row[3] for row in reader)
    servers = list(row[9] for row in reader)
    for row in reader:
        print (row[9])
        for servername in servers:
            if servername not in b:
                b.append(servername)

I'm open to better ways to do this. Any and all help is appreciated. Thanks in advance.

3
  • What is the expected output exactly? You cannot loop over reader twice, at least not without rewinding f to the start with f.seek(0). Not that that would be the efficient way of doing it. Commented Mar 5, 2014 at 17:47
  • So you want to have a Counter() of the 4th column (row[3]) and a unique list of the 10th column (row[9])? You are not using c here, is that needed at all? Commented Mar 5, 2014 at 17:48
  • ^that's exactly what I want. The counter works fine, I want b to contain the unique values of column 10 at the end. Commented Mar 5, 2014 at 17:51

2 Answers 2

2

You are iterating over the reader three times:

severities = Counter(row[3] for row in reader)  # First time
servers = list(row[9] for row in reader)  # Second time
for row in reader:  # Third time

When you iterate the first time, you 'exhaust' it, so it won't yield any item the second and third time.

You should do something like this:

severities = Counter()
servers = []
for row in reader:
    severities[row[3]] += 1
    servers.append(row[9])
    print row[9]

This is enough to make the code work.

Here are some other tips. They aren't required to fix your code, however you'll surely benefit from them:

  • I think you want to place the for servername in servers loop out of the for row in reader loop.
  • If you use a set or an OrderedSet instead of a list for b, you can completely avoid the for servername in servers loop and replace it with a single line:

    b.update(servers)
    
Sign up to request clarification or add additional context in comments.

1 Comment

That was it. Thanks a ton I've been looking at this for far too long.
0

Your best bet is to loop over reader just once and collect the counts and unique names for the servers in your loop:

severities = Counter()
servers = set()

with open(fname, 'rb') as f:
    reader = csv.reader(f)
    for row in reader:
        severities[row[3]] += 1
        servers.add(row[9])

This assumes you don't care about the order servers are listed in in the CSV file.

If order does need to be preserved, use a separate seen set:

severities = Counter()
servers = []

with open(fname, 'rb') as f:
    reader = csv.reader(f)
    seen = set()
    for row in reader:
        severities[row[3]] += 1
        if row[9] not in seen:
            servers.append(row[9])
            seen.add(row[9])

If the file is relatively small, you could also get away with transposing the columns; that's overkill here, but would look like:

with open(fname, 'rb') as f:
    reader = csv.reader(f)
    cols = zip(*reader)  # transpose the rows to columns
    severities = Counter(cols[3])
    servers = set(cols[9])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.