Reputation: 51
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
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
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
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
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