Swapping arguments inside a list of liss of tuples - python

I have a list of lists of tuples in the following form:
a = [[( 0, 1),
( 2, 3),
( 4, 5)],
[( 6, 7),
( 8, 9),
(10, 11)],
[(12, 13),
(14, 15),
(16, 17)]]
What I want to do, is to swap the two arguments inside the tuples.
I have tried the two following options, but without succes, the argumets keep their positions:
for i in range(0, len(a)-1):
for j in range(0, len(a)/2):
a[i][j] = a[i][j][1], a[i][j][0]
a[i][j] = tuple(reversed(a[i][j]))
Every help would be very much appreciated

Tuples are immutable, so you should replace the tuples with the reversed tuples, not try to modify the first tuple in-place:
for lst in a:
for i, x in enumerate(lst):
lst[i] = x[::-1]
This takes updates the items at the position of each tuple in the list with a new reversed tuple (with reversed slice notation [::-1]) using list subscription.
To create a new list of lists with the swapped objects, you can use a list comprehension:
new_a = [[tup[::-1] for tup in lst]for lst in a]

Consider changing your loops to:
for i in range(0, len(a)):
for j in range(0, len(a[i])):
a[i][j] = tuple(reversed(a[i][j]))
In order to iterate over a list of lists (of tuples, in this case), you need to make sure you're specifying the lengths of each part correctly. In len(a)-1 in the outer loop, you don't need the -1, as range(x,y) takes you from x to y-1 already. In the inner loop, you need to specify the length of the inner list.
#Moses has a good answer on why creating a new tuple is the correct approach.

Related

Swapping elements in a list in Python

I am trying to swap the elements of list A i.e. (i,j) turns to (j,-i). But there is an error.
A=[(0,0),(0,1),(1,0),(1,1)]
for i in range(0,len(A)-1):
for j in range(0,len(A)-1):
A[i][j]=A[j][-i]
The error is
in <module>
A[i][j]=A[j][-i]
TypeError: 'tuple' object does not support item assignment
The expected output is
[(0,0),(1,0),(0,-1),(-1,-1)]
What you have is a list of tuples, and tuples are immutable. What you're doing would not be described so much as "swapping elements in a list" as swapping the elements of a tuple (and negating the second one).
If you have
a = (1, 1)
then you could perform this operation like:
b = (a[1], -a[0])
Performing that over a list of items a separate level of abstraction that can be handled in many different ways. For example using a list comprehension:
A = [(0, 0), (0, 1), (1, 0), (1, 1)]
B = [(a[1], -a[0]) for a in A]
or more simply using tuple unpacking:
B = [(j, -i) for i, j in A]

Enumerate does not work with 2d arrays yet range(len()) does?

I heard somewhere that we should all use enumerate to iterate through arrays but
for i in enumerate(array):
for j in enumerate(array[i]):
print(board[i][j])
doesn't work, yet when using range(len())
for i in range(len(array)):
for j in range(len(array[i)):
print(board[i][j])
it works as intended
use it like this:
for idxI, arrayI in enumerate(array):
for idxJ, arrayJ in enumerate(arrayI):
print(board[idxI][idxJ])
Like I wrote enumerate adds an extra counter to each element. Effectively turning you list of elements into a list of tuples.
Example
array = ['a', 'b','c','d']
print(list(enumerate(array)))
gives you this:
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]
So in your case what you want to do it simply add the extra element when iterating over it
for i, item1 in enumerate(array):
for j,item2 in enumerate(array[i]):
print(board[i][j])
Issue was in your case is
for i in enumerate(array):
this i is not an integer but a tuple ('1','a') in my case. And you cant access a list element with an index value of a tuple.
When one uses for i in enumerate(array): it returns a collection of tuples. When working with enumerate, the (index, obj) is returned while range based loops just go through the range specified.
>>> arr = [1,2,3]
>>> enumerate(arr)
<enumerate object at 0x105413140>
>>> list(enumerate(arr))
[(0, 1), (1, 2), (2, 3)]
>>> for i in list(enumerate(arr)):
... print(i)
...
(0, 1)
(1, 2)
(2, 3)
>>>
One has to access the first element of the tuple to get the index in order to further index.
>>> board = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> for idx1,lst in enumerate(board):
... for idx2,lst_ele in enumerate(lst): # could use enumerate(board[i])
... print(lst_ele,end=" ")
...
1 2 3 4 5 6 7 8 9
>>>
Sometimes you do not need both the index and the element so I do not think its always better to use enumerate. That being said, there are plenty of situations where its easier to use enumerate so you can grab the element faster without having to write element = array[idx].
See range() vs enumerate()
"Both are valid. The first solution [range-based] looks more similar to the problem description, while the second solution [enum-based] has a slight optimization where you don’t mutate the list potentially three times per iteration." - James Uejio

How do I print a sub-list where the sum of its elements is the same as the sum of all the elements of the original list?

I have a list of numbers and I have to find a way to print a sub-list where the sum of its elements is the same as the sum of all the elements of the original list.
For example
[5,6,8,6,6,-12] and the result should be [5,6,8]
Method using itertools.combinations. Note that this brute forces all combinations so is applicable for small list sizes like the example given.
>>> numbers = [5,6,8,6,6,-12]
>>> for i in range(len(numbers)):
... print([combo for combo in itertools.combinations(numbers, i) if sum(combo) == sum(numbers)])
output:
[]
[]
[]
[(5, 6, 8), (5, 8, 6), (5, 8, 6)]
[]
[]
You can then decide what to do with the resulting lists.
If you want to remove duplicate combinations from the list you can use itertools.groupby as shown here: https://stackoverflow.com/a/2213973/15981783

Reorganizing a list of tuples into lists of floats

Say I have in python a list of tuples
list1 = [(1,1,1), (2,2,2), (3,3,3)]
If I want to separate them into a list of all the 1 position values, 2 position values and 3 position values I would do:
ones = [tuple[0] for tuple in list1]
twos = [tuple[1] for tuple in list1]
threes = [tuple[2] for tuple in list1]
This sort of way can become very cumbersome the more elements each tuple in that list will have. Is there a cleaner way to do this possibly using the zip method or a reverse of it?
You can use zip for this:
list(zip(*list1))
output:
[(1, 2, 3), (1, 2, 3), (1, 2, 3)]
As #paoloaq noted, you can unpack these into separate lists:
ones, two, threes = list(zip(*list1))
or if you want lists instead of tuples:
ones, two, threes = map(list, list(zip(*list1)))
Sidenote: try avoiding variable names like list and tuple.

What exactly are tuples in Python?

I'm following a couple of Pythone exercises and I'm stumped at this one.
# C. sort_last
# Given a list of non-empty tuples, return a list sorted in increasing
# order by the last element in each tuple.
# e.g. [(1, 7), (1, 3), (3, 4, 5), (2, 2)] yields
# [(2, 2), (1, 3), (3, 4, 5), (1, 7)]
# Hint: use a custom key= function to extract the last element form each tuple.
def sort_last(tuples):
# +++your code here+++
return
What is a Tuple? Do they mean a List of Lists?
The tuple is the simplest of Python's sequence types. You can think about it as an immutable (read-only) list:
>>> t = (1, 2, 3)
>>> print t[0]
1
>>> t[0] = 2
TypeError: tuple object does not support item assignment
Tuples can be turned into new lists by just passing them to list() (like any iterable), and any iterable can be turned into a new tuple by passing it to tuple():
>>> list(t)
[1, 2, 3]
>>> tuple(["hello", []])
("hello", [])
Hope this helps. Also see what the tutorial has to say about tuples.
Why are there separate tuple and list data types? (Python FAQ)
Python Tuples are Not Just Constant Lists
Understanding tuples vs. lists in Python
A tuple and a list is very similar. The main difference (as a user) is that a tuple is immutable (can't be modified)
In your example:
[(2, 2), (1, 3), (3, 4, 5), (1, 7)]
This is a list of tuples
[...] is the list
(2,2) is a tuple
A tuple is a sequence of immutable Python objects. Tuples are sequences, just like lists. The differences between tuples and lists are, the tuples cannot be changed unlike lists and tuples use parentheses, whereas lists use square brackets.
Creating a tuple is as simple as putting different comma-separated values. Optionally you can put these comma-separated values between parentheses also. For example −
tup1 = ('Dog', 'Cat', 2222, 555555);
tup2 = (10, 20, 30, 40, 50 );
tup3 = "a", "b", "c", "d";
The empty tuple is written as two parentheses containing nothing −
tup1 = ();
To write a tuple containing a single value you have to include a comma, even though there is only one value −
tup1 = (45,);
Like string indices, tuple indices start at 0, and they can be sliced, concatenated, and so on.
The best summary of the differences between lists and tuples I have read is this:
One common summary of these more interesting, if subtle, differences is that tuples are heterogeneous and lists are homogeneous. In other words: Tuples (generally) are sequences of different kinds of stuff, and you deal with the tuple as a coherent unit. Lists (generally) are sequences of the same kind of stuff, and you deal with the items individually.
From: http://news.e-scribe.com/397
Tuples are used to group related variables together. It's often more convenient to use a tuple rather than writing yet another single-use class. Granted, accessing their content by index is more obscure than a named member variable, but it's always possible to use 'tuple unpacking':
def returnTuple(a, b):
return (a, b)
a, b = returnTuple(1, 2)
In Python programming, a tuple is similar to a list. The difference between them is that we cannot change the elements of a tuple once it is assigned whereas in a list, elements can be changed.
data-types-in-python

Categories