Merging list items python 3.6 - python

A python list consist of a number of items that is equally divided by 3.
The list looks like this:
the_list = ['ab','cd','e','fgh','i', 'jklm']
I want to merge 3 items at the time for the entire list. How should I do that? (the list could have any number of items as long as the number of items can be divided by 3)
expected_output = ['abcde', 'fghijklm']

You can slice the list while iterating an index over the length of the list with a step of 3 in a list comprehension:
[''.join(the_list[i:i + 3]) for i in range(0, len(the_list), 3)]
You can also create an iterator from the list and use zip with itertools.repeat to group 3 items at a time:
from itertools import repeat
i = iter(the_list)
[''.join(t) for t in zip(*repeat(i, 3))]
Both of the above return:
['abcde', 'fghijklm']

Here's one way using a list comprehension and range:
output = [''.join(the_list[i:i+3]) for i in range(0, len(the_list), 3)]

Related

how to separate different elements in a list in python and put them in a new list

I want to separate different numbers in this list:
[([2437], [0.235]), ([4942], [0.217])]
and put them in new lists. Python returns length of this list equal to 2. I need to have two lists like these: [2437, 4942] and [0.235, 0.217].
How can I able to reach these lists from the above list in python?
You can use the following method for Python 3:
>>> my_list = [([2437], [0.235]), ([4942], [0.217])]
>>> sub_list1, sub_list2 = [[*item1, *item2] for item1, item2 in zip(*my_list)]
>>> sub_list1
[2437, 4942]
>>> sub_list2
[0.235, 0.217]
If it's always two tuples of two single item lists, another way to unpack:
l1, l2 = [[inner_list[i][0] for inner_list in my_list] for i in range(2)]

How do you create a list of repeated tuples in Python?

Say I have a list of tuples, I extract the first tuple from this list and then want to create a new list that simply takes the first tuple and repeats it n times creating a list of tuples? Thanks.
Since tuples are immutable you may be able to do:
lst = [tuples[0]]
repeated = lst * 10 # create a list of the first tuple repeated 10 times
If they contain mutable objects changes in any of them will reflect in all of them, since these are the same objects repeated.
Let say that you have a list like this one:
list_of_tuples = [('foo', 'bar'), ('baz', 'qux')]
If you want to repeat the first tuple n times, you can use itertools.repeat
import itertools
itertools.repeat(list_of_tuples[0], n)
where n is the number of times you want the first tuple to be repeated.
itertools.repeat will return a generator.

Making a list comprehension for a dict within a list within a list

I need to create a list comprehension that extracts values from a dict within a list within a list, and my attempts so far are failing me. The object looks like this:
MyList=[[{'animal':'A','color':'blue'},{'animal':'B','color':'red'}],[{'animal':'C','color':'blue'},{'animal':'D','color':'Y'}]]
I want to extract the values for each element in the dict/list/list so that I get two new lists:
Animals=[[A,B],[C,D]]
Colors=[[blue,red],[blue,Y]]
Any suggestions? Doesn't necessarily need to use a list comprehension; that's just been my starting point so far. Thanks!
Animals = [[d['animal'] for d in sub] for sub in MyList]
Colors = [[d['color'] for d in sub] for sub in MyList]
Gives the desired result:
[['A', 'B'], ['C', 'D']]
[['blue', 'red'], ['blue', 'Y']] # No second 'red'.
What I have done here is take each sub-list, then each dictionary, and then access the correct key.
In a single assignment (with a single list comprehension, and the help of map and zip):
Colors, Animals = map(list,
zip(*[map(list,
zip(*[(d['color'], d['animal']) for d in a]))
for a in MyList]))
If you are fine with tuples, you can avoid the two calls to map => list
EDIT:
Let's see it in some details, by decomposing the nested comprehension.
Let's also assume MyList have m elements, for a total of n objects (dictionaries).
[[d for d in sub] for sub in MyList]
This would iterate through every dictionary in the sublists. For each of them, we create a couple with its color property in the first element and its animal property in the second one:
(d['color'], d['animal'])
So far, this will take time proportional to O(n) - exatly n elements will be processed.
print [[(d['color'], d['animal']) for d in sub] for sub in MyList]
Now, for each of the m sublists of the original list, we have one list of couples that we need to unzip, i.e. transform it into two lists of singletons. In Python, unzip is performed using the zip function by passing a variable number of tuples as arguments (the arity of the first tuple determines the number of tuples it outputs). For instance, passing 3 couples, we get two lists of 3 elements each
>>> zip((1,2), (3,4), (5,6)) #Prints [(1, 3, 5), (2, 4, 6)]
To apply this to our case, we need to pass array of couples to zip as a variable number of arguments: that's done using the splat operator, i.e. *
[zip(*[(d['color'], d['animal']) for d in sub]) for sub in MyList]
This operation requires going through each sublist once, and in turn through each one of the couples we created in the previous step. Total running time is therefore O(n + n + m) = O(n), with approximatively 2*n + 2*m operations.
So far we have m sublists, each one containing two tuples (the first one will gather all the colors for the sublist, the second one all the animals). To obtain two lists with m tuples each, we apply unzip again
zip(*[zip(*[(d['color'], d['animal']) for d in sub]) for sub in MyList]
This will require an additional m steps - the running time will therefore stay O(n), with approximatively 2*n + 4*m operations.
For sake of simplicity we left out mapping tuples to lists in this analysis - which is fine if you are ok with tuples instead.
Tuples are immutable, however, so it might not be the case.
If you need lists of lists, you need to apply the list function to each tuple: once for each of the m sublists (with a total of 2*n elements), and once for each of the 2 first level lists, i.e. Animals and Colors, (which have a total of m elements each). Assuming list requires time proportional to the length of the sequence it is applied to, this extra step requires 2*n + 2*m operations, which is still O(n).

Split a list in smaller 5x5 lists

I need to split a list like:
m=[[1,2,3,4,5,6,7,8,9,0],[11,12,13,14,15,16,17,18,19,20],[21,22,23,24,25,26,27,28,29,30],[31,32,33,34,35,36,37,38,39,40],[41,42,43,44,45,46,47,48,49,50],[51,52,53,54,55,56,57,58,59,60],[61,62,63,64,65,66,67,68,69,70],[71,72,73,74,75,76,77,78,79,80],[81,82,83,84,85,86,87,88,89,90],[91,92,93,94,95,96,97,98,99,100],
into smaller 5x5 lists like:
m1=[[1,2,3,4,5],[11,12,13,14,15],[21,22,23,24,25],[31,32,33,34,35],[41,42,43,44,45]]
m2=[[6,7,8,9,0],[16,17,18,19,20],[26,27,28,29,30],[36,37,38,39,40],[46,47,48,49,50]]
and have a new list that contains these smaller lists:
new_list=[m1,m2,m3,m4]
thanks
First, how can you split a list of 10 elements into two lists of 5 elements?
def split_list(m):
return m[:len(m)//2], m[len(m)//2:]
Now, we want to map that over each list in m:
mm = [split_list(sublist) for sublist in m]
But now we have a list of pairs of lists, not a pair of lists of lists. How do you fix that? zip is the answer: it turns an X of Y of foo into a Y of X of foo:
new_list = list(zip(*mm))
If you don't like the fact that this gives you a list of tuples of lists instead of a list of lists of lists, just use a list comprehension with the list function:
new_list = [list(m) for m in zip(*mm)]
If you want to change it to split any list into N/5 groups of 5, instead of 2 groups of N/2, that's just a matter of changing the first function. A general-purpose grouper function will do that, like the one from the itertools recipes (or see this question for other options, if you prefer):
def grouper(iterable, n=5):
args = [iter(iterable)] * n
return itertools.izip_longest(*args)
So:
new_list = [list(mm) for mm in zip(*grouper(m, 5))]

All combinations of lists using unique indexes in Python

I have N lists of 3 elements. I want to find all combinations between them that don't use the same index twice. Each combination must always have 3 items.
Example:
list1 = [l11, l12, l13]
list2 = [l21, l22, l23]
list3 = [l31, l32, l33]
All combinations possible:
combinaison1 = l11, l22, l33
combinaison2 = l11, l23, l32
combinaison3 = l12, l21,l33
combinaison4= l12, l23, l31
combinaison5=l13, l21, l32
combinaison6= l13, l22, l31
BUT I don't want:
BADcombinaison = l11,l21,l32
How can I do that in python?
Since you want only up to 3 items from 3 or more lists, the first step is to find k-permutations of the list of lists with k-3. I.e. permutations(lists, 3). From there you don't actually have to permute the indexes too, because you want unique indexes. (Note: this allows variable number of lists and also a variable length of the lists, but the lengths of all input and output lists are equal).
Essentially instead of trying to permute indexes, the indexes are just (0, 1, 2) since you specify no repetition of indexes, and the lists are permuted.
from itertools import permutations
# number of lists may vary (>= length of lists)
list1 = ["l11", "l12", "l13"]
list2 = ["l21", "l22", "l23"]
list3 = ["l31", "l32", "l33"]
list4 = ["l41", "l42", "l43"]
lists = [list1, list2, list3, list4]
# lenths of lists must be the same and will be the size of outputs
size = len(lists[0])
for subset in permutations(lists, size):
print([sublist[item_i] for item_i, sublist in enumerate(subset)])

Categories