Extract array from list in python - python

If I have a list like this:
>>> data = [(1,2),(40,2),(9,80)]
how can I extract the the two lists [1,40,9] and [2,2,80] ? Of course I can iterate and extract the numbers myself but I guess there is a better way ?

The unzip operation is:
In [1]: data = [(1,2),(40,2),(9,80)]
In [2]: zip(*data)
Out[2]: [(1, 40, 9), (2, 2, 80)]
Edit: You can decompose the resulting list on assignment:
In [3]: first_elements, second_elements = zip(*data)
And if you really need lists as results:
In [4]: first_elements, second_elements = map(list, zip(*data))
To better understand why this works:
zip(*data)
is equivalent to
zip((1,2), (40,2), (9,80))
The two tuples in the result list are built from the first elements of zip()'s arguments and from the second elements of zip()'s arguments.

List comprehensions save the day:
first = [x for (x,y) in data]
second = [y for (x,y) in data]

There is also
In [1]: data = [(1,2),(40,2),(9,80)]
In [2]: x=map(None, *data)
Out[2]: [(1, 40, 9), (2, 2, 80)]
In [3]: map(None,*x)
Out[3]: [(1, 2), (40, 2), (9, 80)]

Related

How to join elements inside a tuple, in list of tuples?

I have a list like
A = [(1, 2, 3), (3, 4, 5), (3, 5, 7)]
and I want to turn it into
A = [[123], [345], [357]]
Is there any way to do this?
My upper list with tuple comes from permutation function so maybe you can reccomend me to change something in that code
def converter(N):
y = list(str(N))
t = [int(x) for x in y]
f = list(itertools.permutations(t))
return f
r = converter(345)
print(r)
You can swizzle that up like so:
Code:
[[int(''.join(str(i) for i in x))] for x in a]
this converts the integer digits to a str, and then joins them before converting back to an integer.
Test Code:
a = [(1, 2, 3), (3, 4, 5), (3, 5, 7)]
print([[int(''.join(str(i) for i in x))] for x in a])
Results:
[[123], [345], [357]]
For fun (and for proving a radically different approach):
>>> [[sum(i * 10**(len(t) - k - 1) for k, i in enumerate(t))] for t in A]
[[123], [345], [357]]
Use map with a list-comprehension:
[[int(''.join(map(str, x)))] for x in A]
# [[123], [345], [357]]

Comparing a list of tuples

I want to compare a list of tuples, if the first elements are the same then compare the second elements and return the highest.
lis = [(1,10, "n"), (1,15,"n1"), (2,20,"n"),(2,35,"n1"),(3,123,"n"),(3,12,"n1")]
return:
lis = [(1,15,"n1"), (2,35,"n1"), (3,123,"n")]
I'm not sure how to go about this, any help would be appreciated.
I'd use itertools.groupby to first group all items with the same first element together, then max to find the items with the max second element.
Unlike some other answers you may have varying number of elements from different "groups".
from itertools import groupby
from operator import itemgetter
lis = [(1,10, "n"), (1,15,"n1"), (2,20,"n"), (2,35,"n1"), (3,123,"n"),(3,12,"n1")]
lis.sort(key=itemgetter(0)) # groupby requires the iterable to be sorted,
# so making sure it is
grouped_by = groupby(lis, key=itemgetter(0))
output = [max(li, key=itemgetter(1)) for group, li in grouped_by]
print(output)
# [(1, 15, 'n1'), (2, 35, 'n1'), (3, 123, 'n')]
Tuple comparisons do that already, comparing first elements then second and continuing until a tie-breaker is found.
All you need to do is zip the list in such a way to create the correct comparisons:
zip(lis[::2], lis[1::2])
# This produces:
# (1, 10, 'n') (1, 15, 'n1')
# (2, 20, 'n') (2, 35, 'n1')
# (3, 123, 'n') (3, 12, 'n1')
Creates the pairs you need, you can then compare them inside a list-comprehension to get the wanted results:
r = [i if i > j else j for i,j in zip(lis[::2], lis[1::2])]
print(r)
# [(1, 15, 'n1'), (2, 35, 'n1'), (3, 123, 'n')]
The solution using range() and max() functions:
lis = [(1,10, "n"), (1,15,"n1"), (2,20,"n"),(2,35,"n1"),(3,123,"n"),(3,12,"n1")]
result = [max(lis[i:i+2]) for i in range(0, len(lis), 2)]
print(result)
The output:
[(1, 15, 'n1'), (2, 35, 'n1'), (3, 123, 'n')]

How can I find a tuple from a group of tuples with the values closest to a given tuple?

I'm working with python and have a dict where the keys are tuples with 3 values each.
I'm computing another tuple with 3 values, and I want to find the tuple in the keys of the dict with the closest values to this newly computed tuple.
How should I go about doing this?
You are probably looking for the abs() of the difference, e.g.:
>>> from random import randint
>>> d = [tuple(randint(1, 20) for _ in range(3)) for _ in range(5)]
>>> d
[(4, 13, 10), (12, 18, 19), (11, 18, 8), (16, 17, 4), (2, 4, 10)]
>>> k = tuple(randint(1, 20) for _ in range(3))
>>> k
(14, 13, 1)
>>> min(d, key=lambda x: sum(abs(m-n) for m, n in zip(k, x)))
(16, 17, 4)
You could do something like this:
def euclid2(x,y):
return sum((xi-yi)**2 for xi,yi in zip(x,y))
def closestTuple(target,tuples, dist = euclid2):
return min((dist(t,target),t) for t in tuples)[1]
#test:
target = (3,5,1)
tuples = [(3,1,2), (4,1,5), (6,1,7), (4,4,2), (1,5,7)]
print(closestTuple(target,tuples)) #prints (4,4,2)
This finds the tuple which is closest to the target tuple in the Euclidean metric. You could of course pass another function for the dist parameter.
You could try the following (i used a list), and simply iterate over each element, and take the difference between each element in the tuple, then in the end sort the sums of the differences and look for the smallest amount
a = [(1, 2, 3), (3, 4, 5), (5, 6, 7)]
b = (2, 4, 5)
c = []
for x in a:
c[a.index(x)] = 0
for i in range(len(x)):
c[i]+=x[i]-b[i]

How do I organise a nested list representing coordinate-values to a coordinate-list

I would like to change my data-structure that get from my data-files in such a way that I get a list of all coordinate-values for every coordinates (so a list for all coordinates filled with values)
e.g.
for i in range (files):
open file
file_output = [[0,4,6],[9,4,1],[2,5,3]]
second loop
file_output = [[6,1,8],[4,7,3],[3,7,0]]
to
coordinates = [[0,6],[4,1],[6,8],[9,4],[4,7],[1,3],[2,3],[5,7],[3,0]]
It should be noted that I use over 1000 files of this format, which I should merge.
You could also explore the built-in zip() function
>>> l = []
>>> for k,v in zip(a,b):
l.append(zip(k,v))
>>> print l
[[0,6],[4,1],[6,8],[9,4],[4,7],[1,3],[2,3],[5,7],[3,0]]
>>> a = [[0,4,6],[9,4,1],[2,5,3]]
>>> b = [[6,1,8],[4,7,3],[3,7,0]]
>>> from itertools import chain
>>> zip(chain(*a),chain(*b))
[(0, 6), (4, 1), (6, 8), (9, 4), (4, 7), (1, 3), (2, 3), (5, 7), (3, 0)]
>>>
This should be useful.
[zip(i,j) for i in a for j in b]
However it provides list of tuples, which should satisfy your needs.
If there will only be two lists, you can use this as well.
[[i, j] for i in a for j in b]

Converting nested lists to dictionary

Hi please I try to make a dictionary out of the nested lists below and I get a TypeError. Please help me fix it to get the desired output as shown below. Thanks
n1 = [[1,2],[3,4]]
n2 = [[(5,7),(10,22)],[(6,4),(8,11)]]
output = {1:(5,7), 2:(10,22), 3:(6,4), 4:(8,11)}
D1 = {}
for key, value in zip(n1,n2):
D1[key] = value
print D1
TypeError: unhashable type: 'list'
Your approach didn't work, because when you zip n1 and n2, the result will be like this
for key, value in zip(n1,n2):
print key, value
# [1, 2] [(5, 7), (10, 22)]
# [3, 4] [(6, 4), (8, 11)]
So, key is a list. But, it is not hashable. So it cannot be used as an actual key to a dictionary.
You can chain the nested lists to get them flattened and then you can zip them together with izip
from itertools import chain, izip
print dict(izip(chain.from_iterable(n1), chain.from_iterable(n2)))
# {1: (5, 7), 2: (10, 22), 3: (6, 4), 4: (8, 11)}
The beauty of this method is that, it will be very memory efficient, as it doesn't create any intermediate lists. So, this can be used even when the actual lists are very large.
Perhaps not the most pythonic way, but it's short:
In [8]: dict(zip(sum(n1, []), sum(n2, [])))
Out[8]: {1: (5, 7), 2: (10, 22), 3: (6, 4), 4: (8, 11)}
The sum() trick, is used for flattening the list.
Try this:
from itertools import chain
n1 = [[1,2],[3,4]]
n2 = [[(5,7),(10,22)],[(6,4),(8,11)]]
print dict(zip(chain(*n1), chain(*n2))

Categories