0

This refers to the solution stated in Python: Comparing two CSV files and searching for similar items

I want to know what does syntax

masterlist = [row for row in c2]

mean in the solution.

Community
  • 1
  • 1

2 Answers2

3

It is a list comprehension, but in this particular case a useless one. It's more efficient to just do:

masterlist = list(c2)

as that would also copy all elements from the c2 iterable into a new list object.

A list comprehension would normally be used to filter or transform elements from an iterable; say to pick only certain rows, or only a specific column from each row:

masterlist = [row[1] for row in c2]

would pick out just the one column the referenced answer actually uses in their code.

The accepted answer there is missing out on several Python idioms and best practices and operates in quadratic time (duration to process is a function of the size of hosts.csv times the size of masterlist.csv); it should be rewritten to:

import csv

with open('hosts.csv', 'rb') as hosts, open('masterlist.csv', 'rb') as master:
    with open('results.csv', 'wb') as results:    
        reader = csv.reader(hosts)
        writer = csv.writer(results)

        master_indices = {r[1]: i for i, r in enumerate(csv.reader(master), 1)}

        for row in reader:
            index = master_indices.get(row[3])
            if index is not None:
                message = 'FOUND in master list (row {})'.format(index)
            else:
                message = 'NOT FOUND in master list'
            writer.writerow(row)

Here I replaced the list comprehension with a dictionary comprehension instead; creating a dictionary mapping the second column of each CSV row to a row number (produced with enumerate()); now the code to test if row[3] from the hosts.csv file is present in that column is reduced to just a dict.get() call, mapping directly to the row number.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • 1
    Thanks a lot for the revised solution. Greatly appreciate it. I gave another solution an up vote because I just wanted to know the meaning of that one expression. –  Apr 15 '14 at 17:31
  • Sure and not a problem; I got disconnected briefly and didn't get a chance to further elaborate. :-) – Martijn Pieters Apr 15 '14 at 17:33
  • Thanks a lot for the List Comprehension link. Things are much clearer now. I wish I could give both the solutions the up-vote :) –  Apr 15 '14 at 17:36
  • +1 since I learned what the hell is a dictionary comprehension with your answer xD. BTW in which Python version is supported? it is in EVERY 2.7.x version? – Luis Masuelli Apr 15 '14 at 21:17
  • 2.7 and up, and in python 3. See [Alternative to dict comprehension prior to Python 2.7](http://stackoverflow.com/q/21069668) for what to do before 2.7. – Martijn Pieters Apr 15 '14 at 21:50
1

Usually, list comprehensions are a quick way to map one list to another with a transforming expression. It's like calling map() but with syntactic sugar.

e.g.

list_ = [1, 2, 3, 4, 5] #or range(1, 6)
squares = [x*x for x in list_]
print squares
#[1, 4, 9, 16, 25]
Luis Masuelli
  • 12,079
  • 10
  • 49
  • 87
  • It's not like calling `map`, because you can't give an expression to map, only a function. Using your example, `map(x*x, list_)` is a syntax error. Further, on python3 `map` returns a *map object* as opposed to a list. Last, `map` is typically slower than a list comprehension (typical exception is when the function given to map is a python builtin). A better way to think of it might be an inline for loop. – SethMMorton Apr 15 '14 at 21:45
  • actually isn't the same but the difference in map is that instead of x*x you write `lambda x: x*x` but it's practically the same - particularly when you have to explain the concept. – Luis Masuelli Apr 16 '14 at 13:59