Concatanate tuples in list of tuples - python

I have a list of tuples that looks something like this:
tuples = [('a', 10, 11), ('b', 13, 14), ('a', 1, 2)]
Is there a way that i can join them together based on the first index of every tuple to make a each tuple contain 5 elements. I know for a fact there isn't more that 2 of each letter in the tuples, Ie more than 2 'a's or 'b's in the entire list. The other requirement is to use Python2.6. I cant figure out the logic to it. Any help is greatly appreciated.
Desired Output:
tuples = [('a', 10, 11, 1, 2), ('b', 13, 14, 0, 0)]
I have tried creating a new list of first elements and adding the other elements to it but then I only have a list and not list of tuples.
EDIT to provide previous tried code,
Created a new list: templist, resultList = [], []
Populate templist with the first element in every tuple:
for i in tuples:
templist.append(i[0])
elemlist = list(set(templist))
for i in elemlist:
for j in tuples:
if i == j[0]:
resultlist.append((i, j[1], j[2]))
This just returns the same list of tuples, How can i hold onto it and append every j[1] j[2] that corresponds to correct j[0]

Assuming there are only one or two of every letter in the list as stated:
import itertools
tuples = [('a', 10, 11), ('b', 13, 14), ('a', 1, 2)]
result = []
key = lambda t: t[0]
for letter,items in itertools.groupby(sorted(tuples,key=key),key):
items = list(items)
if len(items) == 1:
result.append(items[0]+(0,0))
else:
result.append(items[0]+items[1][1:])
print(result)
Output:
[('a', 10, 11, 1, 2), ('b', 13, 14, 0, 0)]

Related

From Matrix to List

I want to get a list of coordinates from a Matrix, how to do that?
So I want a list in which every element is a pair of number and eliminate the pair that are counted more than once.
Example:
A=array[[1, 2, 34, 1],
[2, 4, 38, 0],
[3, 2, 34, 4],
[4, 2, 4, 2] ]
So now I have a matrix 4x4 and I want to put into a list the 2nd and 3rd columns, such that:
list= [(2,34), (4,38), (2,34), (2,4) ]
And eliminate the pairs that are counted twice so in my example the pair:
(2,34)
since it is counted twice will be removed so the new list will be:
list_new=[(4,38), (2,4)]
Consider that my starting matrix should be very large, thus I want to avoid "for".
Thanks in advance to who will answer
For the 1st part - you can use itemgetter with map/zip/list.
from operator import itemgetter
my_list = list(zip(map(itemgetter(1),A), map(itemgetter(2),A)))
print(my_list) # [(2, 34), (4, 38), (2, 34), (2, 4)]
Then to get the duplicates values you can use collection counters.
import collections
dup_list = [item for item, count in collections.Counter(my_list).items() if count > 1]
print(dup_list) # [(2,34)]
Now, to remove these values from the list use filter.
for item in dup_list:
my_list = list(filter(lambda a: a != item, my_list))
print(my_list) # [(4, 38), (2, 4)]

Merging a tuple filled my any number of tuples in one tuple and returning that sorted

First question for this Problem is: How can I call a function with a tuple of tuples, my programm should be able to handle any number of tuples.
Second question: I found a way, but with defined tuples in my code and it works, so I need a hint how to call the function with a tuple with any number of tuples in it.
My code so far:
def merge(tuples):
tuples = ((2, 3, 4), (1, 6), (5, 1, 7))
largest_tuple = len(tuples[0])
for i in tuples:
largest_tuple = max(largest_tuple, len(i))
new_tuples = []
for i in range(largest_tuple):
tup = []
for j in tuples:
if i < len(j):
tup.append(j[i])
tup.sort()
new_tuples = new_tuples+tup
new_tuple = tuple(new_tuples)
print(new_tuple)
For example:
merge((2, 3, 4), (1, 6), (5, 1, 7))
return:
(1, 2, 5, 1, 3, 6, 4, 7)
Use A Recursive Function:
merged_tuple = [] # Here is where the solution goes
def merge(tuple_set):
for value in tuple_set: # Looping over the current tuple
if type(value) == tuple: # if that value is a tuple
merge(value) # Perform the function all over again
else:
merged_tuple.append(value) # Add the number to the solution set
return tuple(sorted(merged_tuple))

How to group objects (tuples) based on having consecutive attribute value?

I found a similar question here:
How to group a list of tuples/objects by similar index/attribute in python?
which talks about grouping a list of tuples by similar attributes. I have a list of objects; the objects have a 'day' attribute and I want to group these objects based on if they have consecutive 'day' values.
e.g
input = [('a',12),('b',13)('c',15),('d',16),('e',17)]
output:
[[('a',12),('b',13)],[('c',15),('d',16),('e',17)]]
You can do the following:
from itertools import groupby, count
from operator import itemgetter
data = [('a', 12), ('b', 13), ('c', 15), ('c', 16), ('c', 17)]
def key(i, cursor=count(0)):
"""Generate the same key for consecutive numbers"""
return i[1] - next(cursor)
ordered = sorted(data, key=itemgetter(1))
result = [list(group) for _, group in groupby(ordered, key=key)]
print(result)
Output
[[('a', 12), ('b', 13)], [('c', 15), ('c', 16), ('c', 17)]]
The above is based on an old example found in the documentation of Python 2.6, here.
To better illustrate, what is happening, for the following example:
lst = [12, 13, 15, 16, 17]
print([v - i for i, v in enumerate(lst)])
The generated keys are:
[12, 12, 13, 13, 13]
As it can be seen, consecutive runs have the same key.

List to list of tuples conversion

I am brand new to Python. I can change a list to a tuple, for example
li = [1]
tuple(li)
I am trying to create a tuple that gives the item and its position, so a tuple that would come out (1, 0). I have no idea how to get started.
If you want a tuple of tuples, you can use a generator expression like this;
li = [4, 5, 6]
tuple((li[i], i) for i in range(len(li)))
Or with enumerate;
tuple((v, k) for k,v in enumerate(li))
Both will return;
((4, 0), (5, 1), (6, 2))
If you want a list of tuples, you can use a list comprehension expression like this;
[(li[i], i) for i in range(len(li))]
or with enumerate;
[(v,k) for k, v in enumerate(li)]
Both will return;
[(4, 0), (5, 1), (6, 2)]
Use enumerate which does exactly what you need, just with elements and indexes flipped:
> li = [2, 4, 6]
> [(x, i) for i, x in enumerate(li)]
[(2, 0), (4, 1), (6, 2)]
If you want a just one tuple you could do this:
li = (list[1], 1)
The brackets here are the literal syntax for tuples.
If you wanted to do it for all the elements of the list, you could use a list comprehension:
lis = [(list[i], i) for i in range(len(list))]
Which would create a list of tuples were each tuple has the element and its index.
One possible way is to use enumerate,
li = [10, 20, 30]
list(enumerate(li))
prints
[(0, 10), (1, 20), (2, 30)]
If you want the output to be in (item, position) order, you can use,
[(v, k) for k,v in enumerate(li)]
zip with range is another option:
In [4]: li = [2,4,6]
In [5]: zip(li, range(len(li)))
Out[5]: [(2, 0), (4, 1), (6, 2)]

Python accessing slices of a list in order

In Python 2.7, I have a list named data, with some tuples, indexed by the first attribute, e.g.
data = [('A', 1, 2, 3), ('A', 10, 20, 30), ('A', 100, 200, 300),
('B', 1, 2, 3), ('B', 10, 20, 30),
('C', 15, 25, 30), ('C', 1, 20, 22), ('C', 100, 3, 8)]
There is a function f() that will work on any slice of data with the first index matching, e.g.
f( [x[1:] for x in data[:3] )
I want to call f (in proper sequence) on each slice of the array (group of tuples with the same first index) and compile the list of resulting values in a list.
I'm just starting with Python. Here is my solution, is there a better (faster or more elegant) way to do this?
slices = [x for x in xrange(len(data)) if data[x][0] != data[x-1][0]]
result = [f(data[start:end] for start, end in zip( [slices[:-1], slices[1:] )]
Thank you.
If you want to group on the first item of each tuple, you can do so with itertools.groupby():
from itertools import groupby
from operator import itemgetter
[f(list(g)) for k, g in groupby(data, key=itemgetter(0))]
The itemgetter(0) returns the first element of each tuple, which groupby() then gives you iterables for each group based on that value. Looping over each individual g result will then give you a sequence of tuples with just 'A', then 'B', etc.

Categories

Resources