Recursive method to zip list? - python

I have got a nested list of list that looks like the following,
list1 = [[1,2,3],[4,5,6],[7,8,9],[10,11,12]]
However, I would like to find out a method to concatenate the first index of each list with the first index of the other list.
list1 = [[1,4,7,10],[2,5,8,11],[3,6,9,12]]
I have tried doing list comprehension by using the following code
list1 = [[list1[j][i] for j in range(len(list1)) ] for i in range(len(list1[0])) ]
# gives me
# list1 = [[1,4,7,10],[2,5,8,11],[3,6,9,12]]
However, i was hoping alternative methods to achieve the same results, hopefully something that is simpler and more elegant.
Thanks in advance.

zip is a built-in method and does not require outside packages:
>>> list1 = [[1,2,3],[4,5,6],[7,8,9],[10,11,12]]
>>> print([list(x) for x in zip(*list1)])
[[1, 4, 7, 10], [2, 5, 8, 11], [3, 6, 9, 12]]
Notice the *list1! This is needed since list1 is a nested list, so the * unpacks that list's elements to the zip method to zip together. Then, since zip returns a list of tuples we simply convert them to lists (as per your request)

A possible recursion solution can utilize a generator:
def r_zip(d):
yield [i[0] for i in d]
if d[0][1:]:
yield from r_zip([i[1:] for i in d])
print(list(r_zip(list1)))
Output:
[[1, 4, 7, 10], [2, 5, 8, 11], [3, 6, 9, 12]]

x = min([len(list1[i]) for i in range(len(list1))])
[[i[j] for i in list1] for j in range(x)]

Or try using:
>>> list1 = [[1,2,3],[4,5,6],[7,8,9],[10,11,12]]
>>> list(map(list, zip(*list1)))
[[1, 4, 7, 10], [2, 5, 8, 11], [3, 6, 9, 12]]
>>>

Related

Try To Print Map as str/list/join without succeess

def intersection(list_1, list_2):
return map(lambda list0 : list(dict.fromkeys(list0)), [x for x in list_1 if x in list_2 ])
print(intersection([5, 5, 6, 6, 7, 7], [1, 5, 9, 5, 6]))
In lambda the func that deletes duplicate and in [ ] the list (from list comprehension) the transfered to the func by map.
When I try to turn it into a list / str / join this error accourced.
What can I do and why is this happening ?
I added one example run that suppose to print [5,6] but returns error.
Be noticed that the list itself ([ ]) reutrns alone: [5, 5, 6, 6] because of the duplicates in the original lists.
Also if I change the code from one line to block og code it works:
def intersection(list_1, list_2):
my_list = [x for x in list_1 if x in list_2]
small_func = lambda list0 : list(set(list0))
return small_func(my_list)
returns: [5,6]
Thanks !
I don't think you need map here. Your idea was right to convert to dictionary and than convert back to list but you have to do that only once.
def intersection(list_1, list_2):
return list(dict.fromkeys([x for x in list_1 if x in list_2]))
print (intersection([5, 5, 6, 6, 7, 7], [1, 5, 9, 5, 6]))

Identify duplicate lists in list of lists?

How can I compare a list of lists with itself in python in order to:
identify identical sublists with the same items (not necessarily in the same
item order)
delete these duplicate sublists
Example:
list = [ [1, 3, 5, 6], [7, 8], [10, 12], [9], [3, 1, 5, 6], [12, 10] ]
clean_list = [ [1, 3, 5, 6], [7, 8], [10, 12], [9] ]
Any help is greatly appreciated.
I can't seem to figure this out.
I would rebuild the "clean_list" in a list comprehension, checking that the sorted version of the sublist isn't already in the previous elements
the_list = [ [1, 3, 5, 6], [7, 8], [10, 12], [9], [3, 1, 5, 6], [12, 10] ]
clean_list = [l for i,l in enumerate(the_list) if all(sorted(l)!=sorted(the_list[j]) for j in range(0,i))]
print(clean_list)
of course, sorting the items for each iteration is time consuming, so you could prepare a sorted list of sublists:
the_sorted_list = [sorted(l) for l in the_list]
and use it:
clean_list = [the_list[i] for i,l in enumerate(the_sorted_list) if all(l!=the_sorted_list[j] for j in range(0,i))]
result (in both cases):
[[1, 3, 5, 6], [7, 8], [10, 12], [9]]
As many suggested, maybe a simple for loop (no list comprehension there) storing the already seen items in a set would be more performant for the lookup of the duplicates. That alternate solution could be necessary if the input list is really big to avoid the O(n) lookup of all.
An example of implementation could be:
test_set = set()
clean_list = []
for l in the_list:
sl = sorted(l)
tsl = tuple(sl)
if not tsl in test_set:
test_set.add(tsl) # note it down to avoid inserting it next time
clean_list.append(sl)
Create a set. Then for each list in the list, sort it, transform into tuple, then insert into set.
setOfLists = set()
for list in listOfLists:
list.sort()
setOfLists.add(tuple(list))
print setOfLists
You can retransform the tuples in the set into lists again.
Simple for loops will work, but if your dataset is small, e.g. 1k or less, you can use this :
b = []
[b.append(i) for i in a if len([j for j in b if set(j) == set(i)])==0 ]
print b
So heres my take on this.
I def a function that sorts each sublist and appends to a temp list. then I check if the sublist in temp_my_list is 'not' in temp_clean_list and if not then append to new list. this should work for any 2 sets of list. I added some extra list to show some kind of result other than an empty string.
my_list = [[1, 3, 5, 6], [7, 8], [10, 12], [9], [3, 1, 5, 6], [12, 10],[16]]
clean_list = [ [1, 3, 5, 6], [7, 8], [10, 12], [9],[18]]
new_list = []
def getNewList():
temp_my_list = []
temp_clean_list = []
for sublist in my_list:
sublist.sort()
temp_my_list.append(msublist)
for sublist in clean_list:
sublist.sort()
temp_clean_list.append(sublist)
for sublist in temp_my_list:
if sublist not in temp_clean_list:
new_list.append(sublist)
getNewList()
print (new_list)
Resulit:
[[16]]

python how to link sublist together in a list which describe a tree

For example list =[[1,0],[2,1],[6,2],[7,6],[7,8],[15,13],[8,15]]
shows tree
_7_
_6 8_
_2 _15
how to get a new list contain all these number.
like the example list =
[[1,0],[2,1],[6,2],[7,6],[7,8],[15,13],[8,15]]
the output will be new_list=[0,1,2,6,7,8,15,13] (order not important)
My biggest problem is to link [6,2],[7,6],[7,8],[8,15] together
simple, if order doesn't matter:
l =[[1,0],[2,1],[6,2],[7,6],[7,8],[15,13],[8,15]]
# flatten list
t = sum(l,[])
# transform in a set removing duplicate values
# otherwise if u want to keep the order you have to use an OrderedDict
list(set(t)) # [0, 1, 2, 6, 7, 8, 13, 15]
if the order is not important, you can loop through the list and sub-list and check if element is not in new_list:
list = [[1, 0], [2, 1], [6, 2], [7, 6], [7, 8], [15, 13], [8, 15]]
new_list = []
for sub in list:
for elem in sub:
if elem not in new_list:
new_list.append(elem)
print new_list
output:
[1, 0, 2, 6, 7, 8, 15, 13]
Leaving Tree and Graph Theory aside:
list =[[1,0],[2,1],[6,2],[7,6],[7,8],[15,13],[8,15]]
uniq = {}
for i in list:
uniq.update({i[0]: True, i[1]: True})
print(uniq.keys())
>>> [0, 1, 2, 6, 7, 8, 13, 15]
Using python set:
list =[[1,0],[2,1],[6,2],[7,6],[7,8],[15,13],[8,15]]
uniq = set()
for i in list:
uniq.add(i[0])
uniq.add(i[1])
print uniq

Any way to zip to list of lists?

Alright, so I have two lists that look like this
listx = [2, 4, 5, 9, 11]
listy = [3, 5, 9, 12, 14]
Right now, when I do zip, I get this
listz = zip(listx, listy)
listz = [(2,3), (4,5), (5,9), (9, 12), (11,14)]
Is there any way to make this a list of lists instead of an array, like so
listz = [[2,3], [4,5], [5,9], [9,12], [11,14]]
Thanks!
You can use a comprehension:
listz = [list(i) for i in zip(listx, listy)]
or generator expression:
listz = (list(i) for i in zip(listx, listy))
Use map to convert the tuples to lists.
map(list, zip(listx, listy))
Use a list comprehension, and use izip to avoid creating an intermediary list.
import itertools
listz = [list(z) for z in itertools.izip(listx, listy)]
>>> from itertools import izip, imap
>>> listx = [2, 4, 5, 9, 11]
>>> listy = [3, 5, 9, 12, 14]
>>> listz = list(imap(list, izip(listx, listy)))
>>> listz
[[2, 3], [4, 5], [5, 9], [9, 12], [11, 14]]

Python: One-liner to perform an operation upon elements in a 2d array (list of lists)?

I have a list of lists, each containing a different number of strings. I'd like to (efficiently) convert these all to ints, but am feeling kind of dense, since I can't get it to work out for the life of me. I've been trying:
newVals = [int(x) for x in [row for rows in values]]
Where 'values' is the list of lists. It keeps saying that x is a list and can therefore not be the argument if int(). Obviously I'm doing something stupid here, what is it? Is there an accepted idiom for this sort of thing?
This leaves the ints nested
[map(int, x) for x in values]
If you want them flattened, that's not hard either
for Python3 map() returns an iterator. You could use
[list(map(int, x)) for x in values]
but you may prefer to use the nested LC's in that case
[[int(y) for y in x] for x in values]
How about:
>>> a = [['1','2','3'],['4','5','6'],['7','8','9']]
>>> [[int(j) for j in i] for i in a]
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Another workaround
a = [[1, 2, 3], [7, 8, 6]]
list(map(lambda i: list(map(lambda j: j - 1, i)), a))
[[0, 1, 2], [6, 7, 5]] #output
You simply use incorrect order and parenthesis - should be:
inputVals = [['1','2','3'], ['3','3','2','2']]
[int(x) for row in inputVals for x in row]
Or if you need list of list at the output then:
map(lambda row: map(int, row), inputVals)
an ugly way is to use evalf:
>>> eval(str(a).replace("'",""))
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
if you don't mind all your numbers in one array you could go:
>>> a = [['1','2','3'],['4','5','6'],['7','8','9']]
>>> map(int,sum(a,[]))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
In order to map list with any number of dimensions you could use numpy.apply_over_axes
import numpy as np
np.apply_over_axes(lambda x,_:x*2, np.array([[1,2,3],[5,2,1]]),[0])
--------------------
array([[ 2, 4, 6],
[10, 4, 2]])
Unfortunately that doesn't work if you also need to change variable type. Didn't find any library solution for this, so here is the code to do that:
def map_multi_dimensional_list(l, transform):
if type(l) == list and len(l) > 0:
if type(l[0]) != list:
return [transform(v) for v in l]
else:
return [map_multi_dimensional_list(v, transform) for v in l]
else:
return []
map_multi_dimensional_list([[[1,2,3],[5,2,1]],[[10,20,30],[50,20,10]]], lambda x:x*2)
------------------
[[[2, 4, 6], [10, 4, 2]], [[20, 40, 60], [100, 40, 20]]]

Categories