name_masked
name_masked

Reputation: 9794

Iterate every value in list of tuples

I have a list of tuples where the number of rows in the list and the number of columns in tuples of the list will not be constant. i.e.

list = [(a1,b1, …z1), (a2,b2, …, z2),…. ,(am,bm, … , zm )]. It can be compared to the SQL results, as the number of columns change in the sql, the number of columns change in the list of tuples as well.

I have to iterate through each element of every tuple in the list, perform some checks on the value, convert it and return the modified values as a new list of tuples.

i.e.

list_value = [('name1', 1234, 'address1' ), ('name2', 5678, 'address2'), ('name3', 1011, 'addre"ss3')]

I need to access each value to check if the value contains a double quote and enclose the string containing double quote with double quotes(this would be one of the checks). The transformation should return

list_value = [('name1', 1234, 'address1' ), ('name2', 5678, 'address2'), ('name3', 1011, '"addre"ss3"')]

The simplest approach for me would be to do this:

mod_val = [transform(row) for row in list_value]

def transform(row):
   mod_list=[]
   while index < len(row):
...    if isinstance(row[index],basestring):
...       if '"' in row[index]:
...          mod_list.append('"'+row[index]+'"')
...    else:
...       mod_list.append(row[index])
...    index = index+1
... return mod_list

Is there a way to make the code concise using list comprehension?

Upvotes: 0

Views: 131

Answers (2)

Martijn Pieters
Martijn Pieters

Reputation: 1122132

You can nest the list comprehension:

mod_val = [['"{}"'.format(v) if isinstance(v, basestring) and '"' in v else v 
            for v in row]
           for row in list_value]

Your transform() function fails to add strings without quotes in them, even though your sample output indicates those should be passed through unchanged.

Demo:

>>> list_value = [('name1', 1234, 'address1' ), ('name2', 5678, 'address2'), ('name3', 1011, 'addre"ss3')]
>>> [['"{}"'.format(v) if isinstance(v, basestring) and '"' in v else v 
...  for v in row]
... for row in list_value]
[['name1', 1234, 'address1'], ['name2', 5678, 'address2'], ['name3', 1011, '"addre"ss3"']]

Upvotes: 1

Veedrac
Veedrac

Reputation: 60147

If you really want a list comprehension:

mod_val = [['"'+item+'"' if (isinstance(item, str) and '"' in item) else item for item in row] for row in list_value]

Although I'd suggest

def transform(row):
    for item in row:
        if isinstance(item, basestring) and '"' in item:
            item = '"{}"'.format(item)

        yield item

mod_val = [list(transform(row)) for row in list_value]

or

def transform(row):
    if isinstance(item, str) and '"' in item:
        return '"{}"'.format(item)

    return item

mod_val = [map(transform, row) for row in list_value]

Upvotes: 1

Related Questions