Join List of Lists in Python

join list of lists in python

import itertools
a = [['a','b'], ['c']]
print(list(itertools.chain.from_iterable(a)))

How do I concatenate two lists in Python?

Use the + operator to combine the lists:

listone = [1, 2, 3]
listtwo = [4, 5, 6]

joinedlist = listone + listtwo

Output:

>>> joinedlist
[1, 2, 3, 4, 5, 6]

How do I make a flat list out of a list of lists?

Given a list of lists l,

flat_list = [item for sublist in l for item in sublist]

which means:

flat_list = []
for sublist in l:
for item in sublist:
flat_list.append(item)

is faster than the shortcuts posted so far. (l is the list to flatten.)

Here is the corresponding function:

def flatten(l):
return [item for sublist in l for item in sublist]

As evidence, you can use the timeit module in the standard library:

$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' '[item for sublist in l for item in sublist]'
10000 loops, best of 3: 143 usec per loop
$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'sum(l, [])'
1000 loops, best of 3: 969 usec per loop
$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'reduce(lambda x,y: x+y,l)'
1000 loops, best of 3: 1.1 msec per loop

Explanation: the shortcuts based on + (including the implied use in sum) are, of necessity, O(L**2) when there are L sublists -- as the intermediate result list keeps getting longer, at each step a new intermediate result list object gets allocated, and all the items in the previous intermediate result must be copied over (as well as a few new ones added at the end). So, for simplicity and without actual loss of generality, say you have L sublists of I items each: the first I items are copied back and forth L-1 times, the second I items L-2 times, and so on; total number of copies is I times the sum of x for x from 1 to L excluded, i.e., I * (L**2)/2.

The list comprehension just generates one list, once, and copies each item over (from its original place of residence to the result list) also exactly once.

python join strings in list of lists

I guess below will work as you wish.

list = [
['a', 'b', 'c', 'd', 'e'],
['b', 'c', 'd', 'e', 'a'],
['c', 'd', 'e', 'a', 'b'],
['d', 'e', 'a', 'b', 'c'],
['e', 'a', 'b', 'c', 'd']
]

newList = [[' '.join(elem)] for elem in list]
print(newList)

python3 join lists that have same value in list of lists

This can be seen as a graph problem in which you merge subgraphs and need to find the connected components.

Here is your graph:

graph

networkx

Using networkx you can do:

import networkx as nx
from itertools import chain, pairwise
# python < 3.10 use this recipe for pairwise instead
# from itertools import tee
# def pairwise(iterable):
# a, b = tee(iterable)
# next(b, None)
# return zip(a, b)

G = nx.Graph()
G = nx.from_edgelist(chain.from_iterable(pairwise(e) for e in l))
G.add_nodes_from(set.union(*map(set, l))) # adding single items

list(nx.connected_components(G))

output:

[{1, 2, 3, 4}, {5, 6, 7, 8, 9}]

python

Now, you can use pure python to perform the same thing, finding the connected components and merging them.

An example code is nicely described in this post (archive.org link for long term).

In summary, the first step is building the list of neighbors, then a recursive function is used to join the neighbors of neighbors keeping track of the already seen ones.

from collections import defaultdict 

#merge function to merge all sublist having common elements.
def merge_common(lists):
neigh = defaultdict(set)
visited = set()
for each in lists:
for item in each:
neigh[item].update(each)
def comp(node, neigh = neigh, visited = visited, vis = visited.add):
nodes = set([node])
next_node = nodes.pop
while nodes:
node = next_node()
vis(node)
nodes |= neigh[node] - visited
yield node
for node in neigh:
if node not in visited:
yield sorted(comp(node))

example:

merge_common(l)
# [[1, 2, 3, 4], [5, 6, 7, 8, 9]]

Merge elements in list of lists

If you don't want to write a loop you can use map and str.join

>>> list(map(''.join, A))
['baaaa', 'baaaa']

However, the loop using a list comprehension is almost as short to write, and I think is clearer:

>>> [''.join(e) for e in A]
['baaaa', 'baaaa']

Join list of lists into a delimiter separated list of lists

You can use slice assignment

def list_join(seq, delim):
res = [delim]*(len(seq) * 2 - 1)
res[::2] = seq
return res

delim = ['delim']
# empty list
lsts = [[]]
print(list_join(lsts, delim))

# even length
lsts = [[1, 2, 3], [4, 5], [6], [7]]
print(list_join(lsts, delim))

# odd length
lsts = [[1, 2, 3], [4, 5], [6]]
print(list_join(lsts, delim))

Output

[[]]
[[1, 2, 3], ['delim'], [4, 5], ['delim'], [6], ['delim'], [7]]
[[1, 2, 3], ['delim'], [4, 5], ['delim'], [6]]

Join class list of lists

Fix: To merge [['Do sth', 'Shine'], ['Swag'], ['Lag']] you can use a simple list-comprehension

a = [['Do sth', 'Shine'], ['Swag'], ['Lag']]
a = [word for sublist in a for word in sublist]

Best: it would be to modify your add_duty to add only words to the self.duty list, not list

def add_duty(self, new_duty):
if isinstance(new_duty, list):
self.duty.extend(new_duty)
else:
self.duty.append(new_duty)

# call like
manager_employee[2].add_duty(['Do sth', 'Shine']) # with a list
manager_employee[2].add_duty('Swag') # with a string

Better: Use *args syntax, that takes all given argument and store them in a list

def add_duty(self, *new_duty):  # new_duty contains all parameters, as a list
self.duty.extend(new_duty)

# call with any amount of string
manager_employee[2].add_duty('Do sth', 'Shine', 'other')
manager_employee[2].add_duty('Do sth', 'Shine')
manager_employee[2].add_duty('Swag')


Related Topics



Leave a reply



Submit