Frantic
Frantic

Reputation: 51

How to do this list

Let's say that I start with the list:

list1 = [['a', '1', '2'], ['b', '1'], ['c'], ['d']]

and the tuple:

b = (1, 2, 3, 4)

Now I want to get a list like:

c = [['a', '1', '2'], ['b', '1', '1'], ['b', '1', '2'], ['b', '1', '3'], ['b', '1', '4'], ['c'], ['d']]

so every part of b extends a new copy of the old nested list in which b is.

So basically what I want is something like:

c = [i + [j] for j in b if "b" in i else i for i in a]            (1)

Sadly that doesnt work.

So I tried:

c = [[i + [j] for j in b] if "b" in i else i for i in a]

which gives me:

[['a', '1', '2'], [['b', '1', 1], ['b', '1', 2], ['b', '1', 3], ['b', '1', 4]], ['c'], ['d']]

I tried then to split this again but I didn't manage it.

My best try was:

[i[x] if type(i[0]) is list else i for i in c for x in range(len(i))]

Is there maybe a way to make (1) just work or to get the list I get into the result I want? I am kinda stuck. Probably it's quite easy but I don't see the way.

Upvotes: 2

Views: 149

Answers (4)

Tomáš Cerha
Tomáš Cerha

Reputation: 309

The missing step you wanted - to split the result of (1) would be:

reduce(lambda x, y: (x if isinstance(x[0], list) else [x]) +
                    (y if isinstance(y[0], list) else [y]),
       [[i + [str(j)] for j in b] if "b" in i else i for i in a])

Or more readably:

def unnest(x):
    return x if isinstance(x[0], list) else [x]

# Your original (1) attempt (just adding str):
c = [[i + [str(j)] for j in b] if "b" in i else i for i in a]

result = reduce(lambda x, y: unnest(x) + unnest(y), c)

But as Dan suggests, avoiding list comprehension might be even more readable in this case.

Upvotes: 0

ncica
ncica

Reputation: 7206

list1 = [['a', '1', '2'], ['b', '1'], ['c'], ['d']]
b = (1, 2, 3, 4)

b_index = list(filter(lambda index: 'b' in list1[index], range(len(list1))))[0] # searx for list which contains b

list1[b_index] = [list1[b_index]+[item] for item in b]
print (list1)

output:

[['a', '1', '2'], [['b', '1', 1], ['b', '1', 2], ['b', '1', 3], ['b', '1', 4]], ['c'], ['d']]

Upvotes: 2

tomjn
tomjn

Reputation: 5389

If you really want a list comprehension you could try

list1 = [['a', '1', '2'], ['b', '1'], ['c'], ['d']]
b = (1, 2, 3, 4)
c = list1.copy()  # to ensure we don't modify list1
c[1:2] = [list1[1] + [i] for i in b]

Upvotes: 2

Dan
Dan

Reputation: 1587

I would avoid list comprehensions for something this complex:

list1 = [['a', '1', '2'], ['b', '1'], ['c'], ['d']]

b = (1, 2, 3, 4)

new_list = []
for i in list1:
    if 'b' in i:
        extended = [i + [str(j)] for j in b]
        new_list += extended
    else:
        new_list.append(i)

Upvotes: 3

Related Questions