This question already has answers here:
Transpose list of lists
(14 answers)
Closed 27 days ago.
I have a list of lists (will grow) and I don't know how many elements it has, but all the lists will have all the time the same lenth of elements.
For example if I have:
new=[]
new.append(users)
new.append(users_count)
new.append(users_avg)
print(new)
lst2 = [item[0] for item in new]
print(lst2)
In this case the output will be:
[['ser', 'admin', 'emma', 'paul'], [2, 10, 5, 9], [33, 37, 16, 67]]
['ser', 2, 33]
What it is correct, but I would like to get:
['ser', 2, 33]
['admin', 10, 37]
['emma', 5, 16]
['paul', 9, 67]
i.e the first value of each of the lists in a new list, the second value of each list, the third value of each list and so on (always will be three lists but the elements inside will grow).
The builtin zip function is what you are looking for:
users = ['ser', 'admin', 'emma', 'paul']
users_count = [2, 10, 5, 9]
users_avg = [33, 37, 16, 67]
user_tuples = [*zip(users, users_count, users_avg)]
print(user_tuples)
Output:
[('ser', 2, 33), ('admin', 10, 37), ('emma', 5, 16), ('paul', 9, 67)]
you basically want to transpose your nested list. one way to do that is:
lst = [['ser', 'admin', 'emma', 'paul'], [2, 10, 5, 9], [33, 37, 16, 67]]
transposed = list(zip(*lst))
print(transposed)
# [('ser', 2, 33), ('admin', 10, 37), ('emma', 5, 16), ('paul', 9, 67)]
note that the inner sequences are tuples now and not lists.
You can use a list comprehension with zip.
res = [[*x] for x in zip(*new)]
# [['ser', 2, 33], ['admin', 10, 37], ['emma', 5, 16], ['paul', 9, 67]]
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I have the following lists and I'd like to get the consecutive integers from all the list.
list = [[3, 10, 15, 88],
[4, 11, 30],
[1, 6, 12, 50, 74]]
It should return [10, 11, 12].
If there are more than one consecutive list like
list = [[3, 10, 15, 88],
[4, 11, 30],
[5, 6, 12, 50, 74]]
It should return both [3,4,5] and [10,11,12].
I'd like to know the most efficient solution. Thank you.
l = [[3, 10, 15, 88],
[4, 11, 30],
[5, 6, 12, 50, 74]]
result = [[elem-1,elem,elem+1] for elem in l[1] if (elem+1) in l[2] and (elem-1) in l[0] ]
[[3, 4, 5], [10, 11, 12]]
for elem in l[1] : we are going to iterate over middle list and check if elem+1in the next list and elem-1 in previous list
Try this in just one line using product:
from itertools import product
l = [[3, 10, 15, 88],
[4, 11, 30],
[5, 6, 12, 50, 74]]
result = [[i,j,k] for i,j,k in product(*l) if k==j+1 and j==i+1]
The result will be:
In [7]: result
Out[7]: [[3, 4, 5], [10, 11, 12]]
Note that: Do not use list as a variable name. it is predefined in python and you will override its main functionality.
you can simply do this to get the required answer
from operator import itemgetter
data = [ 1,4,5,6,10,15,16,17,18,22,25,26,27,28]
for k, g in groupby(enumerate(data), lambda (i, x): i-x):
print map(itemgetter(1), g)
Result:
[1]
[4, 5, 6]
[10]
[15, 16, 17, 18]
[22]
[25, 26, 27, 28]
with simple reasoning
l = [[3, 10, 15, 88],
[4, 11, 30],
[5, 6, 12, 50, 74]]
l2 = [(index,j) for index,i in enumerate(l) for j in i] # flattening the list
l2 = sorted(l2, key= lambda x: x[1]) # sorting the list
# the sorted list has the below structure (sublist_number, item)
output = []
current_group = []
temp = []
for i in l2:
if(len(temp) == 0):
temp.append(i[1])
current_group.append(i[0])
else:
if(i[1] - temp[-1] != 1): # that means not consecutive
if(len(temp) == 3):
output.append(temp.copy())
temp.clear()
current_group.clear()
temp.append(i[1])
current_group.append(i[0])
else:
if(i[0] not in current_group):
temp.append(i[1])
current_group.append(i[0])
print(output)
[[3, 4, 5], [10, 11, 12]]
I have a list of tables, where each table is a list of lists. I'd like to extract the columns from each table to get a lists of columns. An example should clarify:
input=[[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]],[[13,14,15],[16,17,18]]]
output=[[[1,4],[7,10],[13,16]],[[2,5],[8,11],[14,17]],[[3,6],[9,12],[15,18]]]
I know I can probably use several for loops, but it feels like there should be a nice one liner to do this.
I intend to assign the results to variables:
a,b,_=output
With a single table, I can extract the columns with:
>>>input=[[1,2,3],[4,5,6]]
>>>list(zip(*input))
[(1, 4), (2, 5), (3, 6)]
or for assignment:
>>>a,b,_=zip(*input)
>>>a
(1, 4)
>>>b
(2, 5)
But for a list of tables, I haven't been able to do it. Here are some of the things I've tried unsuccessfully:
>>>list(zip(*zip(*input)))
[([1, 2, 3], [4, 5, 6]), ([7, 8, 9], [10, 11, 12]), ([13, 14, 15], [16, 17, 18])]
>>>[list(zip(*inp)) for inp in input]
[[(1, 4), (2, 5), (3, 6)], [(7, 10), (8, 11), (9, 12)], [(13, 16), (14, 17), (15, 18)]]
>>>[[x,y,z] for x,y,z in [zip(*inp) for inp in input]]
#same as above
>>> [[x,y] for inp in input for x,y in zip(*inp)]
[[1, 4], [2, 5], [3, 6], [7, 10], [8, 11], [9, 12], [13, 16], [14, 17], [15, 18]]
And nested/unpacked assignment didn't work for me either:
>>>[[a,b,_]]=[zip(*inp) for inp in input]
ValueError: too many values to unpack (expected 1)
>>>[*a,*b,*_]=[[x,y] for x,y in [zip(*inp) for inp in input]]
SyntaxError: two starred expressions in assignment
Is there a one-liner to do what I'm trying to do?
Edit: Note that while the example is specifically 3 tables with 2 rows and 3 columns each, my actual use case has unknown numbers of tables and rows.
I ended up using this line in my code:
list(zip(*[zip(*inp) for inp in input]))
You got close with that last attempt. You need one more, well-chosen nesting level. EDIT: I added the final zip step to get the desired ordering. I also used that "star" notation to help show how to extend the concept.
given = [[[1,2,3],[4,5,6]],
[[7,8,9],[10,11,12]],
[[13,14,15],[16,17,18]]]
f1 = [[[a, b] for a, b in zip(list1, list2)] for list1, list2 in given]
print(f1)
f2 = list(zip(*f1))
print(f2)
Output (edited for readability)
[[[1, 4], [2, 5], [3, 6]],
[[7, 10], [8, 11], [9, 12]],
[[13, 16], [14, 17], [15, 18]]]
[([1, 4], [7, 10], [13, 16]),
([2, 5], [8, 11], [14, 17]),
([3, 6], [9, 12], [15, 18])]
The second one has tuples instead of lists at the middle level; is that okay? If not, can you fix it? (left as an exercise for the student ... )
I have a list of lists in python:
[[1],[2],[3,4],[5,6],[7,8,9,10,11],[12,13,14,15,16],[17]]
I would like to combine the sublists into a single sublist if they hold the same number of elements:
[[1,2,17],[3,4,5,6],[7,8,9,10,11,12,13,14,15,16]]
Is there a simple way of doing this?
Use groupby and chain from itertools
Ex:
from itertools import groupby, chain
lst = [[1],[2],[3,4],[5,6],[7,8,9,10,11],[12,13,14,15,16],[17]]
result = [list(chain.from_iterable(v)) for k, v in groupby(sorted(lst, key=lambda h: len(h)), lambda x: len(x))]
print(result)
Output:
[[1, 2, 17], [3, 4, 5, 6], [7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]
sorted(lst, key=lambda h: len(h)) to sort your list by len
then use groupby to group your list by len of list
A "simpler" approach without itertools:
dictByLength = {}
for i in mylist:
dictByLength[len(i)] = dictByLength.get(len(i), []) + i
print(list(dictByLength.values()))
output:
[[1, 2, 17], [3, 4, 5, 6], [7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]
Here is my approach (without using itertools):
l = [[1],[2],[3,4],[5,6],[7,8,9,10,11],[12,13,14,15,16],[17]]
# create one sublist for each possible length
m = [[] for size in range(len(max(l, key=len)))]
# append to each size-sublist, the appropriate sublist
for sub_l in l:
size = len(sub_l)
m[size - 1] += sub_l
# remove empty sub lists
m = [sub_m for sub_m in m if sub_m]
print(m)
[[1, 2, 17], [3, 4, 5, 6], [7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]
This question already has answers here:
Removing duplicates in lists
(56 answers)
Closed 6 years ago.
In this program I want to remove the duplicate values from the list. This is what i wrote:
list = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
def loop():
for a in range(len(list)-1):
for b in range(a+1,len(list)):
if list[a] == list[b]:
del list[a]
print(list)
loop()
But, it's giving me this error:
Can you help me?
If you have numpy then you can do (I renamed your list to l to avoid ambiguity):
import numpy as np
l = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
l_no_duplicates = list( np.unique(l) )
The common approach to get a unique collection of items is to use a set. Sets are unordered collections of distinct objects.
list = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
newList = list(set(list))
[1, 2, 3, 5, 8, 13, 34, 21, 55, 89]
Do something like the following:
create new_list
for item in list:
if item not in new_list:
add item to new_list
list = new_list
In Python:
list = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
print list
new_list = []
for item in list:
if item not in new_list:
new_list.append(item)
list = new_list
print list
Now run python filename.py and you will see the difference between two lists.
Suppose I have this list:
[ [5, 44, 73] , [7, 21, 99], [1, 32, 100] ]
What is the MOST efficient way to turn it into this list?
[ 5, 7, 1, 44, 21, 32, 73, 99, 100 ]
Notice, I grab the first from each. Then the 2nd element from each.
Of course, this function needs to be done with X elements.
I've tried it, but mine has many loops,and I think it's too long and complicated.
Thanks.
>>> L1 = [ [5, 44, 73] , [7, 21, 99], [1, 32, 100] ]
>>> L2 = []
>>> map(L2.extend, zip(*L1))
>>> L2
[5, 7, 1, 44, 21, 32, 73, 99, 100]
import itertools
list(itertools.chain(*zip(*L1)))
If you need lists of varying length:
import itertools
[x for x in itertools.chain(*itertools.izip_longest(*L1)) if x is not None]
"One-liner" != "Pythonic"
It is bad form to use a list comprehension just to implement a for loop in one line. Save the list expressions or generator expressions for times when you want the results of the expression. The clearest and most Pythonic to my eye is (for sublists of equal length):
L1 = [ [5, 44, 73] , [7, 21, 99], [1, 32, 100] ]
L2 = []
for nextitems in zip(*L1):
L2.extend(nextitems)
Sure you could write this as:
[ L2.extend(nextitems) for nextitems in zip(*L1) ]
but this generates a list of [None,None,...] as long as the number of items in each sublist, since extend() returns None. And what are we doing with this list? Nothing, and so it gets discarded immediately. But the reader has to look at this for a bit before realizing that this list is "built" for the purpose of running extend() on each created sublist.
The Pythonicness is given by the use of zip and *L1 to pass the sublists of L as args to zip. List comprehensions are generally regarded as Pythonic too, but when they are used for the purpose of creating a list of things, not as a clever shortcut for a for loop.
As long as all sublists are the same length:
def flattener(nestedlist):
if not nestedlist: return []
return [ x for i in range(len(nestedlist[0]))
for x in [sublist[i] for sublist in nestedlist]
]
For example,
print flattener([ [5, 44, 73] , [7, 21, 99], [1, 32, 100] ])
emits exactly the flat list you desire.
If not all sublist need be the same length, what do you want to happen when some are longer, some shorter...? A precise spec is needed if you need to take such inequality into account.
>>> L1 = [ [5, 44, 73] , [7, 21, 99], [1, 32, 100] ]
>>> L2 = list(sum(zip(*L1), ()))
>>> L2
[5, 7, 1, 44, 21, 32, 73, 99, 100]
Here is an O^2 solution, it assumes all the inner arrays are of the same length
parent = [ [5, 44, 73] , [7, 21, 99], [1, 32, 100] ]
final = []
for i in range(len(parent[0])):
for x in range(len(parent)):
final.append(parent[x][i])
print final # [5, 7, 1, 44, 21, 32, 73, 99, 100]
A simple list comprehension to the second depth:
>>> L = [ [5, 44, 73] , [7, 21, 99], [1, 32, 100] ]
>>> [x for li in zip(*L) for x in li]
[5, 7, 1, 44, 21, 32, 73, 99, 100]
pretty nice. If the sublists are of uneven length, it is not as elegant to express:
>>> L = [ [5, 44, 73] , [7], [1, 32, 100, 101] ]
>>> [li[idx] for idx in xrange(max(map(len, L))) for li in L if idx < len(li)]
[5, 7, 1, 44, 32, 73, 100, 101]
These solutions are of complexity O(n), where n is the total number of elements.
As long as all the sublists are of the same length:
lst = [[5, 44, 73] , [7, 21, 99], [1, 32, 100]]
list(reduce(lambda l, r: l + r, zip(*lst)))
Edit: This will work with sublists of different lengths:
lst = [[5, 44, 73, 23] , [7, 21, 99], [1, 32, 100]]
list(filter(lambda p: p is not None, reduce(lambda x, y: x + y, map(None, *lst))))