I have a 2 dimensional list. Example:
list = [[1,4,7], [2,5,8], [3,6,9]]
I need to make a new list whose elements are the elements of each sub-element preserving the order.
Example:
final_list = [1,2,3,4,5,6,7,8,9]
Q: The new list must take the first element of each list first, then the
second, and so on..
A:
You can use zip and a list comprehension.
list_1 = [1,4,7]
list_2 = [2,5,8]
list_3 = [3,6,9]
print([x for lst in zip(list_1, list_2, list_3) for x in lst])
# outputs > [1, 2, 3, 4, 5, 6, 7, 8, 9]
For your new list, you could do the same, but first unpack the list with a *
new_list = [[1,4,7], [2,5,8], [3,6,9]]
print([x for lst in zip(*new_list) for x in lst])
# outputs > [1, 2, 3, 4, 5, 6, 7, 8, 9]
first transpose the list matrix with zip then chaining all the inner list together with itertools
also rename variable list to lst, not a good practice to use builtin list as variable name
import itertools
lst = [[1,4,7], [2,5,8], [3,6,9]]
final_list = list(itertools.chain.from_iterable(zip(*lst)))
# final_list = [1, 2, 3, 4, 5, 6, 7, 8, 9]
Related
I have a list:
example_list = [x, y, [1, 2, 3], [4,5,6]]
I need to turn into two lists:
j = [x, y, 1, 2, 3]
k = [x, y, 4, 5, 6]
This example list does not come up with regularity, only when there are two objects on one page that I am scraping--say contact_page. Generally, there is only one contact so the list is:
normal_example_list = [x, y, [1, 2, 3]]
where 'x' comes from function 1, 'y' comes from function 2, and [1, 2, 3] comes from function 3 (contact_page) and I put them all together with normal_example_list.append()
when there is only one list from contact_page I can just flatten it out. I am looking for a rule that would iterate over a list and remove the 1st list within the list and then the 2nd list within the list, while keeping all other variables in the list in their positions.
Thinking this through after retyping my query something like
p = []
for i in contact_page:
p.append(x)
p.append(y)
p.append(i)
This would be more cumbersome to make functional in my code, but it may work. I was hoping for a fix like (in words)
if example_list contains a list:
new_list1 = [values common to both lists, [first list within list]]
new_list2 = [values common to both lists, [second list within list]]
from that I can flatten it out.
It appears you want to extract all the lists from the input list and create a list for each, combined with all the non-list elements from the input list.
Something like:
xs = [1, 2, [3, 4, 5], [6, 7, 8], 9, [10]]
singles = [x for x in xs if not isinstance(x, list)]
result = [singles + x for x in xs if isinstance(x, list)]
print(result)
Gets you:
[[1, 2, 9, 3, 4, 5], [1, 2, 9, 6, 7, 8], [1, 2, 9, 10]]
I have a dictionary with varying numbers of elements. e.g.:
data = {"Tr1":[1,2,3], "Tr2": [4,5,6], "Tr3": [7,8,9]}
I would like to extract all values from the dictionary, and write it to a new separate list. e.g.:
outputData = [1,2,3,4,5,6,7,8,9]
Thanks in advance!
You could also do it with list comprehension:
>>> [i for x in data.values() for i in x]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
One way is to use dict.values() to get the lists and flatten the result using itertools.chain.from_iterable:
from itertools import chain
outputData = list(chain.from_iterable(data.values()))
print(outputData)
#[1, 2, 3, 4, 5, 6, 7, 8, 9]
c = list(itertools.chain.from_iterable(zip(list_a, list_b)))
I have two list list_a and list_b
list_a has one more element than list_b and i want to insert between two elements of a one element of b.
Unfortunately this method from above deletes the last element of list_a in the result list c.
How can i fix this?
Python 2.7
I don't know enough about itertools to say much more, but if you only need to append the last element of list_a to c, why not do just that?
import itertools
list_a = [1,3,5,7,9]
list_b = [2,4,6,8]
c = list(itertools.chain.from_iterable(zip(list_a, list_b)))
# c is [1, 2, 3, 4, 5, 6, 7, 8]
c.append(list_a[-1])
# after append c is [1, 2, 3, 4, 5, 6, 7, 8, 9]
I have two lists and need to compare them by their largest element, if that is tied, their 2nd largest element, and if that is tied, 3rd largest etc iterating to the entire array.
For example:
list1= [0,2,3,6,12]
list2= [1,2,3,6,12]
list3= [1,4,5,8,12]
list4= [1,4,5,9,12]
So list4 > list3 > list2 > list1.
I wrote a function that accomplishes this:
def compare(x,y):
if sorted(x)==sorted(y):
return "Tie"
for index in range(len(x)-1,-1,-1):
if sorted(x)[index]>sorted(y)[index]:
return x
elif sorted(x)[index]<sorted(y)[index]:
return y
I was wondering if there was a much neater and more efficient way of writing the function because it doesn't seem very Pythonic.
Edit: comparing lists by using "<" and ">" will sort the lists from the smallest index to largest index, not largest index to smallest index. Reversed would make ">" and "<" the simplest solutions.
How about this?
>>> list1= [0,2,3,6,12]
>>> list2= [1,2,3,6,12]
>>> list3= [1,4,5,8,12]
>>> list4= [1,4,5,9,12]
>>> def sort_lists_by_maxes(*lists):
return sorted(lists, key=lambda x: sorted(x, reverse=True), reverse=True)
>>> sort_lists_by_maxes(list1, list2, list3, list4)
[[1, 4, 5, 9, 12], [1, 4, 5, 8, 12], [1, 2, 3, 6, 12], [0, 2, 3, 6, 12]]
The lists are compared by their individually sorted values, and you can feed as many lists as you would like into the function as arguments.
sorted of sorted is good, but I'm partial to:
#!/usr/local/cpython-3.3/bin/python
list1 = [0, 2, 3, 6, 12]
list2 = [1, 2, 3, 6, 12]
list3 = [1, 4, 5, 8, 12]
list4 = [1, 4, 5, 9, 12]
metalist = [ list1, list2, list3, list4 ]
for sublist in metalist:
sublist.sort(reverse=True)
metalist.sort(reverse=True)
print(metalist)
It should be faster and take less memory. It's also more clear to novices.
Say I have list1 = [1,2,3,4] and list2 = [5,6,7,8]. How would I compare the first element, 1, in list1 with the first element, 5, in list2? And 2 with 6, 3 with 7, and so on.
I'm trying to use a for loop for this, but I'm not sure how to do it. I understand that doing for x in list1 just checks an element x to all elements in list1, but I don't know how to do it when comparing two lists the way I described.
You can traverse both lists simultaneously using zip:
for (x, y) in zip(list1, list2): do_something
The 'zip' function gives you [(1,5), (2,6), (3,7), (4,8)], so in loop iteration N you get the Nth element of each list.
The default comparison operators compare lists in lexicographical order. So you can say things like:
>>> [1, 2, 3, 4] < [5, 6, 7, 8]
True
If instead you want to compute the elementwise comparison, you can use map and cmp (or any other operator:
>>> map(cmp, [1, 2, 3, 4], [5, 6, 7, 8])
[-1, -1, -1, -1]
If your result is going to be a new list, then you can use a list comprehension:
new_list = [ some_function(i, j) for i, j in zip(list1, list2) ]
Here's a real example of the above code:
>>> list1 = [1, 2, 3, 4]
>>> list2 = [1, 3, 4, 4]
>>> like_nums = [ i == j for i, j in zip(list1, list2) ]
>>> print like_nums
[True, False, False, True]
This will make a list of bools that show whether items of the same index in two lists are equal to each other.
Furthermore, if you use the zip function, there is a way to unzip the result when you are done operating on it. Here's how:
>>> list1 = [1, 2, 3, 4]
>>> list2 = [1, 3, 4, 4]
>>> new_list = zip(list1, list2) # zip
>>> print new_list
[(1, 1), (2, 3), (3, 4), (4, 4)]
>>> newlist1, newlist2 = zip(*new_list) # unzip
>>> print list(newlist1)
[1, 2, 3, 4]
>>> print list(newlist2)
[1, 3, 4, 5]
This could be useful if you need to modify the original lists, while also comparing the elements of the same index in some way.