Adding a tuple element in a list [duplicate] - python

This question already has an answer here:
Python += with a list and a tuple [duplicate]
(1 answer)
Closed 7 years ago.
<class 'list'>'s insert method helps to add element ((1,2), (3, 4)) in a lst with expected output lst = [((1,2), (3, 4))],
lst = []
lst.insert(0, ((1,2), (3, 4)))
lst.insert(1, ((5, 6), (7, 8)))
But += operator does not give same result(lst = [(1, 2), (3, 4)]).
lst = []
lst += ((1,2), (3, 4))
+= operator internally calls __iadd__ method.
Why __iadd__ does not add element in a way class <'list'>'s insert(index,element) method does ? Because maintaining index needs extra name-value pair in my merge sort code is a big overhead..

x += y, where x and y are list-like will create a new list with the contents of y concatenated to the contents of x.
Since you don't want to append the contents of the tuple ((1,2), (3, 4)) to lst, instead want the tuple added to the list, you should lst.append(((1,2), (3, 4))) instead.
>>> lst = []
>>> lst.append(((1, 2), (3, 4)))
>>> lst.append(((5, 6), (7, 8)))
>>> lst
[((1, 2), (3, 4)), ((5, 6), (7, 8))]

Related

Given a List get all the combinations of tuples without duplicated results

I have a list=[1,2,3,4]
And I only want to receive tuple results for like all the positions in a matrix, so it would be
(1,1),(1,2),(1,3),(1,4),(2,1),(2,2),(2,3),(2,4),(3,1),(3,2),(3,3),(3,4),(4,1),(4,2),(4,3),(4,4)
I've seen several codes that return all the combinations but i don't know how to restrict it only to the tuples or how to add the (1,1),(2,2),(3,3),(4,4)
Thank you in advance.
You just need a double loop. A generator makes it easy to use
lst = [1,2,3,4]
def matrix(lst):
for i in range(len(lst)):
for j in range(len(lst)):
yield lst[i], lst[j]
output = [t for t in matrix(lst)]
print(output)
Output:
[(1, 1), (1, 2), (1, 3), (1, 4), (2, 1), (2, 2), (2, 3), (2, 4), (3, 1), (3, 2), (3, 3), (3, 4), (4, 1), (4, 2), (4, 3), (4, 4)]
If you just want to do this for making pairs of all symbols in the list
tuple_pairs = [(r,c) for r in lst for c in lst]
If you have instead some maximum row/colum numbers max_row and max_col you could avoid making the lst=[1,2,3,4] and instead;
tuple_pairs = [(r,c) for r in range(1,max_row+1) for c in range(1,max_col+1)]
But that's assuming that the lst's goal was to be = range(1, some_num).
Use itertools.product to get all possible combinations of an iterable object. product is roughly equivalent to nested for-loops with depth specified by the keyword parameter repeat. It returns an iterator.
from itertools import product
lst = [1, 2, 3, 4]
combos = product(lst, repeat=2)
combos = list(combos) # cast to list
print(*combos, sep=' ')
Diagonal terms can be found in a single loop (without any extra imports)
repeat = 2
diagonal = [(i,)*repeat for i in lst]
print(*diagonal sep=' ')
You can do that using list comprehension.
lst=[1,2,3,4]
out=[(i,i) for i in lst]
print(out)
Output:
[(1, 1), (2, 2), (3, 3), (4, 4)]

Sort out pairs with same members but different order from list of pairs

From the list
l =[(3,4),(2,3),(4,3),(3,2)]
I want to sort out all second appearances of pairs with the same members in reverse order. I.e., the result should be
[(3,4),(2,3)]
What's the most concise way to do that in Python?
Alternatively, one might do it in a more verbose way:
l = [(3,4),(2,3),(4,3),(3,2)]
L = []
omega = set([])
for a,b in l:
key = (min(a,b), max(a,b))
if key in omega:
continue
omega.add(key)
L.append((a,b))
print(L)
If we want to keep only the first tuple of each pair:
l =[(3,4),(2,3),(4,3),(3,2), (3, 3), (5, 6)]
def first_tuples(l):
# We could use a list to keep track of the already seen
# tuples, but checking if they are in a set is faster
already_seen = set()
out = []
for tup in l:
if set(tup) not in already_seen:
out.append(tup)
# As sets can only contain hashables, we use a
# frozenset here
already_seen.add(frozenset(tup))
return out
print(first_tuples(l))
# [(3, 4), (2, 3), (3, 3), (5, 6)]
This ought to do the trick:
[x for i, x in enumerate(l) if any(y[::-1] == x for y in l[i:])]
Out[23]: [(3, 4), (2, 3)]
Expanding the initial list a little bit with different orderings:
l =[(3,4),(2,3),(4,3),(3,2), (1,3), (3,1)]
[x for i, x in enumerate(l) if any(y[::-1] == x for y in l[i:])]
Out[25]: [(3, 4), (2, 3), (1, 3)]
And, depending on whether each tuple is guaranteed to have an accompanying "sister" reversed tuple, the logic may change in order to keep "singleton" tuples:
l = [(3, 4), (2, 3), (4, 3), (3, 2), (1, 3), (3, 1), (10, 11), (10, 12)]
[x for i, x in enumerate(l) if any(y[::-1] == x for y in l[i:]) or not any(y[::-1] == x for y in l)]
Out[35]: [(3, 4), (2, 3), (1, 3), (10, 11), (10, 12)]
IMHO, this should be both shorter and clearer than anything posted so far:
my_tuple_list = [(3,4),(2,3),(4,3),(3,2)]
set((left, right) if left < right else (right, left) for left, right in my_tuple_list)
>>> {(2, 3), (3, 4)}
It simply makes a set of all tuples, whose members are exchanged beforehand if first member is > second member.

Delete item in a list in Python [duplicate]

This question already has answers here:
Is there a simple way to delete a list element by value?
(25 answers)
Closed 7 years ago.
How to find and delete only one element in a list in Python?
# Example:deleting only the first (1,2) in the list
a = [(4, 5), (1, 2), (7, 5), (1, 2), (5, 2)]
# result expected
a = [(4, 5), (7, 5), (1, 2), (5, 2)]
Use the list.remove() method to remove the first occurrence, in-place:
a.remove((1, 2))
Demo:
>>> a = [(4, 5), (1, 2), (7, 5), (1, 2), (5, 2)]
>>> a.remove((1, 2))
>>> a
[(4, 5), (7, 5), (1, 2), (5, 2)]
See the Mutable Sequence Types documentation:
s.remove(x)
same as del s[s.index(x)]
and s.index() only ever finds the first occurrence.
Hello if you want to delete any thing in lists
use these codes
mylist.pop(element_order) #mylist stands for your list and
#element_order stands for the order of element is the list and if it is the
#first element it will be 0
or you can use
mylist.remove(the_element)
note that in the pop it is a method not a list
mylist.pop(0)
print mylist
dont use
mylist = mylist.pop(0)

max second element in tuples python [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Sorting or Finding Max Value by the second element in a nested list. Python
I've written a program that gives me a list of tuples. I need to grab the tuple with with the max number in the second value.
(840, 32), (841, 3), (842, 4), (843, 4), (844, 6), (845, 6), (846, 12), (847, 6), (848, 10), (849, 4), ..snip...
I need to get back (840,32) because 32 is the highest second number in the tuple. How can I achieve this? I've tried a variety of ways but keep getting stuck here is the complete code:
D = {}
def divisor(n):
global D
L = []
for i in range(1,n+1):
if n % i == 0:
L.append(i)
D[n] = len(L)
for j in range(1001):
divisor(j)
print(D.items())
Use max() with lambda:
In [22]: lis=[(840, 32), (841, 3), (842, 4), (843, 4), (844, 6), (845, 6), (846, 12), (847, 6), (848, 10), (849, 4)]
In [23]: max(lis, key=lambda x:x[1])
Out[23]: (840, 32)
or operator.itemgetter:
In [24]: import operator
In [25]: max(lis, key=operator.itemgetter(1))
Out[25]: (840, 32)

Python Easiest Way to Sum List Intersection of List of Tuples

Let's say I have the following two lists of tuples
myList = [(1, 7), (3, 3), (5, 9)]
otherList = [(2, 4), (3, 5), (5, 2), (7, 8)]
returns => [(1, 7), (2, 4), (3, 8), (5, 11), (7, 8)]
I would like to design a merge operation that merges these two lists by checking for any intersections on the first element of the tuple, if there are intersections, add the second elements of each tuple in question (merge the two). After the operation I would like to sort based upon the first element.
I am also posting this because I think its a pretty common problem that has an obvious solution, but I feel that there could be very pythonic solutions to this question ;)
Use a dictionary for the result:
result = {}
for k, v in my_list + other_list:
result[k] = result.get(k, 0) + v
If you want a list of tuples, you can get it via result.items(). The resulting list will be in arbitrary order, but of course you can sort it if desired.
(Note that I renamed your lists to conform with Python's style conventions.)
Use defaultdict:
from collections import defaultdict
results_dict = defaultdict(int)
results_dict.update(my_list)
for a, b in other_list:
results_dict[a] += b
results = sorted(results_dict.items())
Note: When sorting sequences, sorted sorts by the first item in the sequence. If the first elements are the same, then it compares the second element. You can give sorted a function to sort by, using the key keyword argument:
results = sorted(results_dict.items(), key=lambda x: x[1]) #sort by the 2nd item
or
results = sorted(results_dict.items(), key=lambda x: abs(x[0])) #sort by absolute value
A method using itertools:
>>> myList = [(1, 7), (3, 3), (5, 9)]
>>> otherList = [(2, 4), (3, 5), (5, 2), (7, 8)]
>>> import itertools
>>> merged = []
>>> for k, g in itertools.groupby(sorted(myList + otherList), lambda e: e[0]):
... merged.append((k, sum(e[1] for e in g)))
...
>>> merged
[(1, 7), (2, 4), (3, 8), (5, 11), (7, 8)]
This first concatenates the two lists together and sorts it. itertools.groupby returns the elements of the merged list, grouped by the first element of the tuple, so it just sums them up and places it into the merged list.
>>> [(k, sum(v for x,v in myList + otherList if k == x)) for k in dict(myList + otherList).keys()]
[(1, 7), (2, 4), (3, 8), (5, 11), (7, 8)]
>>>
tested for both Python2.7 and 3.2
dict(myList + otherList).keys() returns an iterable containing a set of the keys for the joined lists
sum(...) takes 'k' to loop again through the joined list and add up tuple items 'v' where k == x
... but the extra looping adds processing overhead. Using an explicit dictionary as proposed by Sven Marnach avoids it.

Categories

Resources