This question already has answers here:
Flatten an irregular (arbitrarily nested) list of lists
(51 answers)
Closed 1 year ago.
I have the following list:
my_list=[[['A','B'],'C'],[['S','A'],'Q']]
How I can remove the bracket from the first two elements?
output:
my_list=[['A','B','C'],['S','A','Q']]
Slice it in?
for a in my_list:
a[:1] = a[0]
This produces the desired output:
[x[0]+[x[1]] for x in my_list]
my_list=[
[['A','B'],'C'],
[['S','A'],'Q'],
]
result = [[item1, item2, item3] for (item1, item2), item3 in my_list]
>>> result
[['A', 'B', 'C'], ['S', 'A', 'Q']]
You can use the flattening solution in Cristian's answer on Flatten an irregular list of lists.
>>> [list(flatten(x)) for x in my_list]
[['A', 'B', 'C'], ['S', 'A', 'Q']]
Other people have already given the oneline solutions, but let's take a step back and think about how to approach this problem, so you can solve it for yourself.
The tools you need:
for [element] in list: Iterate over each element in a list
list[i]: Get the ith element of a list
list.append(element): Add an element to a list
Let's start with the simple case. We have [['A','B'],'C'] and want ['A','B','C'].
We want to
Get the sublist ['A', 'B']
Get the single item that isn't in the sublist, 'C'
Add the single item into the sublist
Make the sublist the main list
Sometimes it's easiest to sketch these things out in the python shell:
>>> l = [['A','B'],'C']
>>> l[0]
['A', 'B']
>>> l[1]
'C'
>>> l[0].append(l[1])
>>> l = l[0]
>>> l
['A', 'B', 'C']
Now, we can build up a function to do this
def fix_single_element(element):
"""
Given a list in the format [['A','B'],'C']
returns a list in the format ['A','B','C']
"""
# We use copy since we don't want to mess up the old list
internal_list = element[0].copy()
last_value = element[1]
internal_list.append(last_value)
return internal_list
Now we can use that:
>>> for sublist in my_list:
... print(sublist)
...
[['A', 'B'], 'C']
[['S', 'A'], 'Q']
Note that the sublists are exactly the problem we just solved.
>>> new_list = []
>>> for sublist in my_list:
... new_list.append(fix_single_element(sublist))
...
>>> new_list
[['A', 'B', 'C'], ['S', 'A', 'Q']]
There are LOTS of ways to do any particular task, and this is probably not the "best" way, but it's a way that will work. Focus on writing code you understand and can change, not the shortest code, especially when you start.
Related
I have two list of lists and I want to capture only the matches of the first element between these 2 list of lists. More formally, let us say I have 2 list of lists with
list1=[['a','b','c'],['e','f','g'],['i','j','k']]
list2=[['a','m','n'],['i','m','k'],['q','r','s']]
and I want to implement a function such that def function(list1,list2) returns me [['a','b','c'],['i','j','k']] as the result since there is a match between first elements in the inner list namely 'a' and 'i'. Please note that it returns the elements from the first list.
If the lists are large, indexing via a dictionary can turn this into faster set operations
>>> d1 = {l[0]:l for l in list1}
>>> d2 = {l[0] for l in list2}
>>> result = [d1[key] for key in (d1.keys() & d2)]
>>> result
[['a', 'b', 'c'], ['i', 'j', 'k']]
Try:
def function(list1, list2):
return [l1 for l1 in list1 if any(l2[0]==l1[0] for l2 in list2)]
>>> function(list1, list2)
[['a', 'b', 'c'], ['i', 'j', 'k']]
list1 = [['apple','b','c'] ,['dolly','e','f']]
list2 =[['awsme','b','c'] ,['dad','e','f'],['tally','e','f']]
list_combine = [item for sublst in zip(list1, list2) for item in sublst]
print(list_combine)
Expected Output:
list_combine = [['apple','b','c'] ,['dolly','e','f'],['awsme','b','c'] ,['dad','e','f'],['tally','e','f']]
How to merge 2 unequal nested list into single nested list in python
You can just use the '+' operator to join 2 lists.
list_combine = list1 + list2
print(list_combine)
Output
list_combine = [['apple','b','c'] ,['dolly','e','f'],['awsme','b','c'] ,['dad','e','f'],['tally','e','f']]
You may simply concatenate the two lists by defining a new variable like list3 or whatever you call.
Also due to PEP8, I just modified your code in a more Pythonic way so that it would be more readable. Things like space before comma in not suggested, but after that is recommended. This recommendation is not just in Python, but also it is the better way to write in English grammatically too.
You may check this out and inform me should you have any doubts and questions regarding my answer:
list1 = [['apple', 'b', 'c'], ['dolly', 'e', 'f']]
list2 = [['awsme', 'b', 'c'], ['dad', 'e', 'f'], ['tally', 'e', 'f']]
list3 = list1 + list2
print(list3)
I hope it would be useful.
This question already has answers here:
How do I iterate through two lists in parallel?
(8 answers)
Closed 3 years ago.
I am currently trying to re-sort a list I got from parsing a website.
I have tried everything but I don't think I found the best solution to my problem.
Let's say we have the following list:
my_list = [['a', 'b', 'c'], ['a', 'b', 'c']]
What I am trying to convert it to:
new_list = [['a', 'a'], ['b', 'b'], ['c', 'c']]
I came up with the following loop:
result = [[], [], []]
for sublist in my_list:
for i in range(0, len(sublist)):
result[i].append(sublist[i])
print(result)
# output: [['a', 'a'], ['b', 'b'], ['c', 'c']]
My method is not the best I assume and I am searching for the most pythonic way to do it if you know what I'm saying.
The Python builtin function zip() is your friend here.
From the official documentation, it
returns an iterator of tuples, where the i-th tuple contains the i-th element from each of the argument sequences or iterables.
What that means is that given two lists, zip(list1, list2) will pair list1[0] with list2[0], list1[1] with list2[1], and so on.
In your case, the lists you want to zip together are inside another list, my_list, so you can unpack it with *my_list. Since zip() returns an iterator, you want to create a list out of the return value of zip(). Final solution:
new_list = list(zip(*my_list))
I have written a code which exactly does what you want. You should use map after zip to convert tuples to lists.
Code:
my_list = [['a', 'b', 'c'], ['a', 'b', 'c']]
my_new_list = list(map(list, zip(my_list[0], my_list[1])))
print(my_new_list)
Output:
>>> python3 test.py
[['a', 'a'], ['b', 'b'], ['c', 'c']]
I am searching through a list like this:
my_list = [['a','b'],['b','c'],['a','x'],['f','r']]
and I want to see which elements come with 'a'. So first I have to find lists in which 'a' occurs. Then get access to the other element of the list. I do this by abs(pair.index('a')-1)
for pair in my_list:
if 'a' in pair:
print( pair[abs(pair.index('a')-1)] )
Is there any better pythonic way to do that?
Something like: pair.index(not 'a') maybe?
UPDATE:
Maybe it is good to point out that 'a' is not necessarily the first element.
in my case, ['a','a'] doesn't happen, but generally maybe it's good to choose a solution which handles this situation too
Are you looking for elements that accompany a? If so, a simple list comprehension will do:
In [110]: [x for x in my_list if 'a' in x]
Out[110]: [['a', 'b'], ['a', 'x']]
If you just want the elements and not the pairs, how about getting rid of a before printing:
In [112]: [(set(x) - {'a'}).pop() for x in my_list if 'a' in x]
Out[112]: ['b', 'x']
I use a set because a could either be the first or second element in the pair.
If I understand your question correctly, the following should work:
my_list = filter(
lambda e: 'a' not in e,
my_list
)
Note that in python 3, this returns a filter object instance. You may want to wrap the code in a list() command to get a list instance instead.
That technique works ok here, but it may be more efficient, and slightly more readable, to do it using sets. Here's one way to do that.
def paired_with(seq, ch):
chset = set(ch)
return [(set(pair) - chset).pop() for pair in seq if ch in pair]
my_list = [['a','b'], ['b','c'], ['x','a'], ['f','r']]
print(paired_with(my_list, 'a'))
output
['b', 'x']
If you want to do lots of tests on the same list, it would be more efficient to build a list of sets.
def paired_with(seq, ch):
chset = set(ch)
return [(pair - chset).pop() for pair in seq if ch in pair]
my_list = [['a','b'], ['b','c'], ['x','a'], ['f','r']]
my_sets = [set(u) for u in my_list]
print(my_sets)
print(paired_with(my_sets, 'a'))
output
[{'b', 'a'}, {'c', 'b'}, {'x', 'a'}, {'r', 'f'}]
['b', 'x']
This will fail if there's a pair like ['a', 'a'], but we can easily fix that:
def paired_with(seq, ch):
chset = set(ch)
return [(pair - chset or chset).pop() for pair in seq if ch in pair]
my_list = [['a','b'], ['b','c'], ['x','a'], ['f','r'], ['a', 'a']]
my_sets = [set(u) for u in my_list]
print(paired_with(my_sets, 'a'))
output
['b', 'x', 'a']
This question already has answers here:
Finding intersection/difference between python lists
(7 answers)
Closed 9 years ago.
How do you find or keep only the sublists of a list if it the sublist is also present within another list?
lsta = [['a','b','c'],['c','d','e'],['e','f','g']]
lstb = [['a','b','c'],['d','d','e'],['e','f','g']]
I'd like to do something like set(lsta) & set(lstb)
Desired_List = [['a','b','c'],['e','f','g']]
The reason I'd like to do something like set is for it's speed as I'm doing this on a very large list where efficiency is quite important.
Also, slightly unrelated, what if I wanted to subtract lstb from lsta to get
Desired_List2 = [['d','d','e']]
Better change the list of lists to list of tuples, then you can easily use the set operations:
>>> tupa = map(tuple, lsta)
>>> tupb = map(tuple, lstb)
>>> set(tupa).intersection(tupb)
set([('a', 'b', 'c'), ('e', 'f', 'g')])
>>> set(tupa).difference(tupb)
set([('c', 'd', 'e')])
If your sub-lists need to remain lists, use a list comprehension
Intersection:
>>> [i for i in lsta if i in lstb]
[['a', 'b', 'c'], ['e', 'f', 'g']]
Subtraction:
>>> [i for i in lsta if i not in lstb]
[['c', 'd', 'e']]
I have written a C module a while ago for this:
>>> lsta = [['a','b','c'],['c','d','e'],['e','f','g']]
>>> lstb = [['a','b','c'],['d','d','e'],['e','f','g']]
>>> list(boolmerge.andmerge(lsta, lstb))
>>> import boolmerge
[['a', 'b', 'c'], ['e', 'f', 'g']]
This is O(n) time, and require the lists to be sorted.