Related
How do I convert
[(1,), (2,), (3,)]
to
[1, 2, 3]
Using simple list comprehension:
e = [(1,), (2,), (3,)]
[i[0] for i in e]
will give you:
[1, 2, 3]
#Levon's solution works perfectly for your case.
As a side note, if you have variable number of elements in the tuples, you can also use chain from itertools.
>>> a = [(1, ), (2, 3), (4, 5, 6)]
>>> from itertools import chain
>>> list(chain(a))
[(1,), (2, 3), (4, 5, 6)]
>>> list(chain(*a))
[1, 2, 3, 4, 5, 6]
>>> list(chain.from_iterable(a)) # More efficient version than unpacking
[1, 2, 3, 4, 5, 6]
Here is another alternative if you can have a variable number of elements in the tuples:
>>> a = [(1,), (2, 3), (4, 5, 6)]
>>> [x for t in a for x in t]
[1, 2, 3, 4, 5, 6]
This is basically just a shortened form of the following loops:
result = []
for t in a:
for x in t:
result.append(x)
>>> a = [(1,), (2,), (3,)]
>>> zip(*a)[0]
(1, 2, 3)
For a list:
>>> list(zip(*a)[0])
[1, 2, 3]
>>> a = [(1,), (2,), (3,)]
>>> b = map(lambda x: x[0], a)
>>> b
[1, 2, 3]
With python3, you have to put the list(..) function to the output of map(..), i.e.
b = list(map(lambda x: x[0], a))
This is the best solution in one line using python built-in functions.
You can also use sum function as follows:
e = [(1,), (2,), (3,)]
e_list = list(sum(e, ()))
And it also works with list of lists to convert it into a single list, but you will need to use it as follow:
e = [[1, 2], [3, 4], [5, 6]]
e_list = list(sum(e, []))
This will give you [1, 2, 3, 4, 5, 6]
There's always a way to extract a list from another list by ...for...in.... In this case it would be:
[i[0] for i in e]
Using operator or sum
>>> from functools import reduce ### If python 3
>>> import operator
>>> a = [(1,), (2,), (3,)]
>>> list(reduce(operator.concat, a))
[1, 2, 3]
(OR)
>>> list(sum(a,()))
[1, 2, 3]
>>>
If in python > 3 please do the import of reduce from functools
like from functools import reduce
https://docs.python.org/3/library/functools.html#functools.reduce
You can also unpack the tuple in the list comprehension:
e = [(1,), (2,), (3,)]
[i for (i,) in e]
will still give:
[1, 2, 3]
One Liner yo!
list(*zip(*[(1,), (2,), (3,)]))
In these situations I like to do:
a = [(1,), (2,), (3,)]
new_a = [element for tup in a for element in tup]
This works even if your tuples have more than one element. This is equivalent to doing this:
a = [(1,), (2,), (3,)]
new_a = []
for tup in a:
for element in tup:
new_a.append(element)
If it is already a numpy array, use ravel() method which is more faster than list comprehension.
If it is already a list, list comprehension is better.
Most of the answers above only prints the first element not all the elements
For numpy arrays
#arr = np.array([(1,2), (2,3), (3,4)])
#faster than list comprehension
arr.ravel().tolist()
#output => [1,2,2,3,3,4]
For list
list_ = [(1,2), (2,3), (3,4)]
[x for y in list_ for x in y]
#output => [1,2,2,3,3,4]
This question already has answers here:
Transpose list of lists
(14 answers)
Closed 8 years ago.
Let's say I have a SINGLE list [[1,2,3],[4,5,6]]
How do I transpose them so they will be: [[1, 4], [2, 5], [3, 6]]?
Do I have to use the zip function? Is the zip function the easiest way?
def m_transpose(m):
trans = zip(m)
return trans
Using zip and *splat is the easiest way in pure Python.
>>> list_ = [[1,2,3],[4,5,6]]
>>> zip(*list_)
[(1, 4), (2, 5), (3, 6)]
Note that you get tuples inside instead of lists. If you need the lists, use map(list, zip(*l)).
If you're open to using numpy instead of a list of lists, then using the .T attribute is even easier:
>>> import numpy as np
>>> a = np.array([[1,2,3],[4,5,6]])
>>> print(*a)
[1 2 3] [4 5 6]
>>> print(*a.T)
[1 4] [2 5] [3 6]
The exact way of use zip() and get what you want is:
>>> l = [[1,2,3],[4,5,6]]
>>> [list(x) for x in zip(*l)]
>>> [[1, 4], [2, 5], [3, 6]]
This code use list keyword for casting the tuples returned by zip into lists.
You can use map with None as the first parameter:
>>> li=[[1,2,3],[4,5,6]]
>>> map(None, *li)
[(1, 4), (2, 5), (3, 6)]
Unlike zip it works on uneven lists:
>>> li=[[1,2,3],[4,5,6,7]]
>>> map(None, *li)
[(1, 4), (2, 5), (3, 6), (None, 7)]
>>> zip(*li)
[(1, 4), (2, 5), (3, 6)]
# ^^ 7 missing...
Then call map again with list as the first parameter if you want the sub elements to be lists instead of tuples:
>>> map(list, map(None, *li))
[[1, 4], [2, 5], [3, 6]]
(Note: the use of map with None to transpose a matrix is not supported in Python 3.x. Use zip_longest from itertools to get the same functionality...)
zip() doesn't seem to do what you wanted, using zip() you get a list of tuples. This should work though:
>>> new_list = []
>>> old_list = [[1,2,3],[4,5,6]]
>>> for index in range(len(old_list[0])):
... new_list.append([old_list[0][index], old_list[1][index]])
...
>>> new_list
[[1, 4], [2, 5], [3, 6]]
I am newbie to Python and need to convert a list to dictionary. I know that we can convert a list of tuples to a dictionary.
This is the input list:
L = [1,term1, 3, term2, x, term3,... z, termN]
and I want to convert this list to a list of tuples (or directly to a dictionary) like this:
[(1, term1), (3, term2), (x, term3), ...(z, termN)]
How can we do that easily in Python?
>>> L = [1, "term1", 3, "term2", 4, "term3", 5, "termN"]
# Create an iterator
>>> it = iter(L)
# zip the iterator with itself
>>> zip(it, it)
[(1, 'term1'), (3, 'term2'), (4, 'term3'), (5, 'termN')]
You want to group three items at a time?
>>> zip(it, it, it)
You want to group N items at a time?
# Create N copies of the same iterator
it = [iter(L)] * N
# Unpack the copies of the iterator, and pass them as parameters to zip
>>> zip(*it)
Try with the group clustering idiom:
zip(*[iter(L)]*2)
From https://docs.python.org/2/library/functions.html:
The left-to-right evaluation order of the iterables is guaranteed.
This makes possible an idiom for clustering a data series into
n-length groups using zip(*[iter(s)]*n).
List directly into a dictionary using zip to pair consecutive even and odd elements:
m = [ 1, 2, 3, 4, 5, 6, 7, 8 ]
d = { x : y for x, y in zip(m[::2], m[1::2]) }
or, since you are familiar with the tuple -> dict direction:
d = dict(t for t in zip(m[::2], m[1::2]))
even:
d = dict(zip(m[::2], m[1::2]))
Using slicing?
L = [1, "term1", 2, "term2", 3, "term3"]
L = zip(L[::2], L[1::2])
print L
Try this ,
>>> L = [1, "term1", 3, "term2", 4, "term3", 5, "termN"]
>>> it = iter(L)
>>> [(x, next(it)) for x in it ]
[(1, 'term1'), (3, 'term2'), (4, 'term3'), (5, 'termN')]
>>>
OR
>>> L = [1, "term1", 3, "term2", 4, "term3", 5, "termN"]
>>> [i for i in zip(*[iter(L)]*2)]
[(1, 'term1'), (3, 'term2'), (4, 'term3'), (5, 'termN')]
OR
>>> L = [1, "term1", 3, "term2", 4, "term3", 5, "termN"]
>>> map(None,*[iter(L)]*2)
[(1, 'term1'), (3, 'term2'), (4, 'term3'), (5, 'termN')]
>>>
[(L[i], L[i+1]) for i in xrange(0, len(L), 2)]
The below code will take care of both even and odd sized list :
[set(L[i:i+2]) for i in range(0, len(L),2)]
I have a nested list of tuples of 97510 values like this:
a = [ (1,2,3), (3,4,5), (5,4,2)]
every first value (index=0) is unique and I need to find other index=0 items that have the same index=1 items
In the example , I need to find the second and third tuples where the the second item '4' is common .
How do I do it ?
If you want to find all matches:
>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> for inner in a:
... d[inner[1]].append(inner)
...
>>> d
defaultdict(<type 'list'>, {2: [(1, 2, 3)], 4: [(3, 4, 5), (5, 4, 2)]})
>>> d[4]
[(3, 4, 5), (5, 4, 2)]
If you want to pick out all matches for a particular second value:
>>> filter(lambda inner: inner[1] == 4, a)
[(3, 4, 5), (5, 4, 2)]
Edit: As pointed out in the comments, a list comprehension is preferable as it is more efficient for such work:
>>> [inner for inner in a if inner[1] == 4]
[(3, 4, 5), (5, 4, 2)]
Using timeit shows the list comprehension is about 2.5 times faster (on my machine anyway):
>>> timeit.timeit('[inner for inner in a if inner[1] == 4]', 'a=[(1,2,3), (3,4,5), (5, 4, 2)]')
2.5041549205780029
>>> timeit.timeit('filter(lambda inner: inner[1] == 4, a)', 'a=[(1,2,3), (3,4,5), (5, 4, 2)]')
6.328679084777832
Here is one way to do it:
>>> result = defaultdict(list)
>>> for item in a:
>>> result[item[1]].append(item)
>>> result
defaultdict(<type 'list'>, {2: [(1, 2, 3)], 4: [(3, 4, 5), (5, 4, 2)]})
This will result in a dictionary of lists where all items with the same second value are in one list, with that value as the key.
Another alternative:
from operator import itemgetter
from itertools import groupby
a = [ (1,2,3), (3,4,5), (5,4,2)]
b = groupby(sorted(a), itemgetter(1))
for val, group in b:
print val, list(group)
# 2 [(1, 2, 3)]
# 4 [(3, 4, 5), (5, 4, 2)]
Note that you can also use groupby:
from itertools import groupby
data = [ (1,2,3), (3,4,5), (5,4,2)]
res = groupby(sorted(data), key=lambda x: x[1])
Edited as per comment
Played around with the problem and found one more solution - however not the best one, but:
inputVals = [(1,2,3), (3,4,5), (5,4,2), (2,2,3), (7,3,1)]
for val in set(x[1] for x in inputVals):
print val, list(set(sval for sval in inputVals if sval[1] == val))
What is the Pythonic approach to achieve the following?
# Original lists:
list_a = [1, 2, 3, 4]
list_b = [5, 6, 7, 8]
# List of tuples from 'list_a' and 'list_b':
list_c = [(1,5), (2,6), (3,7), (4,8)]
Each member of list_c is a tuple, whose first member is from list_a and the second is from list_b.
In Python 2:
>>> list_a = [1, 2, 3, 4]
>>> list_b = [5, 6, 7, 8]
>>> zip(list_a, list_b)
[(1, 5), (2, 6), (3, 7), (4, 8)]
In Python 3:
>>> list_a = [1, 2, 3, 4]
>>> list_b = [5, 6, 7, 8]
>>> list(zip(list_a, list_b))
[(1, 5), (2, 6), (3, 7), (4, 8)]
In python 3.0 zip returns a zip object. You can get a list out of it by calling list(zip(a, b)).
You can use map lambda
a = [2,3,4]
b = [5,6,7]
c = map(lambda x,y:(x,y),a,b)
This will also work if there lengths of original lists do not match
Youre looking for the builtin function zip.
I am not sure if this a pythonic way or not but this seems simple if both lists have the same number of elements :
list_a = [1, 2, 3, 4]
list_b = [5, 6, 7, 8]
list_c=[(list_a[i],list_b[i]) for i in range(0,len(list_a))]
The output which you showed in problem statement is not the tuple but list
list_c = [(1,5), (2,6), (3,7), (4,8)]
check for
type(list_c)
considering you want the result as tuple out of list_a and list_b, do
tuple(zip(list_a,list_b))
I know this is an old question and was already answered, but for some reason, I still wanna post this alternative solution. I know it's easy to just find out which built-in function does the "magic" you need, but it doesn't hurt to know you can do it by yourself.
>>> list_1 = ['Ace', 'King']
>>> list_2 = ['Spades', 'Clubs', 'Diamonds']
>>> deck = []
>>> for i in range(max((len(list_1),len(list_2)))):
while True:
try:
card = (list_1[i],list_2[i])
except IndexError:
if len(list_1)>len(list_2):
list_2.append('')
card = (list_1[i],list_2[i])
elif len(list_1)<len(list_2):
list_1.append('')
card = (list_1[i], list_2[i])
continue
deck.append(card)
break
>>>
>>> #and the result should be:
>>> print deck
>>> [('Ace', 'Spades'), ('King', 'Clubs'), ('', 'Diamonds')]
Or map with unpacking:
>>> list(map(lambda *x: x, list_a, list_b))
[(1, 5), (2, 6), (3, 7), (4, 8)]
>>>
One alternative without using zip:
list_c = [(p1, p2) for idx1, p1 in enumerate(list_a) for idx2, p2 in enumerate(list_b) if idx1==idx2]
In case one wants to get not only tuples 1st with 1st, 2nd with 2nd... but all possible combinations of the 2 lists, that would be done with
list_d = [(p1, p2) for p1 in list_a for p2 in list_b]
Like me, if anyone needs to convert it to list of lists (2D lists) instead of list of tuples, then you could do the following:
list(map(list, list(zip(list_a, list_b))))
It should return a 2D List as follows:
[[1, 5],
[2, 6],
[3, 7],
[4, 8]]