Creating a tuple with n entries for n lists - python

If I have a function that creates a random number of lists and I want the final result to return a tuple containing those lists - is it at all possible to do this?
Since tuples are immutable and the number of elements in a tuple cannot be changed once it has been created, then how can one be automatically generated which contains n entries for n lists?
Unlike lists, expanding the entries of a tuple can't simply be changed with a command like .append().
EDIT: It just dawned on me that I could create a tuple with a really large number of entries e.g. tuple = (a,b,c,d,e,f,g,h, ... to infinity) to cover n lists and then pass on the values of the tuple, which contain a list, to a new tuple with the exact number of n entries but this seems like a really inefficient method.

Create a list of lists, then pass that list to the built in tuple() function:
my_lists = [[1, 2], [5, 7], [8, 9]]
my_tuple = tuple(my_lists)
print(my_tuple)
Output
([1, 2], [5, 7], [8, 9])

Related

Given multiple lists, how to find the values between neighboring lists?

I have multiple lists of increasing numbers. The elements in each list are strictly greater than those in its previous neighbor. i.e. [1,2,3], [6,7,8], [10,11,12].
How to find the numbers between neighboring lists? In this case, the results would be [4,5], [9].
If there are only two lists, I can use something like
a = [1,2,3]
b = [4,5,6]
result = list(range(a[-1]+1,b[0]))
but I can't think of a simple and fast way to construct a loop to do this if I have more than two lists.
Assuming that the lists are sorted and that the elements in each list are strictly increasing you can use a loop to iterate over the indices of the lists and uses the range() function to generate a list of numbers between the last element of the current list and the first element of the next list. The results are appended to the results array:
def find_gaps(lists):
gaps = []
for i in range(len(lists) - 1):
gap = list(range(lists[i][-1] + 1, lists[i + 1][0]))
gaps.append(gap)
return gaps
lists = [[1, 2, 3], [6, 7, 8], [10, 11, 12]]
print(find_gaps(lists))
The resulting list of arrays will contain the numbers between neighboring lists: [[4, 5], [9]]. The complexity of the find_gaps() function is O(n), where n is the number of lists.
You can try the following:
a,b,c=[1,2,3], [6,7,8], [10,11,12]
c=[a,b,c]
result=[]
for i in range(len(c)-1):
result.append(list(range(c[i][-1]+1,c[i+1][0])))
print(result)

Assign inner list to new variable - Python

I stumble upon some issue with list. I have nested list like this one
[[1, 2, 3], [4, 5, 6],[7, 8, 9]]
This list can be arbitrarily large and inner list does not need to be in the same length(size).
What I would like to achieve is to take out each inner list and assign to new variable.
This means in our toy example the following.
Var1=[1,2,3]
Var2=[4,5,6]
Var3=[7,8,9]
I can index it manually in toy example each inner list, but this not desired result. I need to store as separate variable each inner list. Moreover I prefer function to do this for me.
What I need is a function that takes nested list and assigns each inner list to variable automatically. Input of function should be nested list and output should be each inner list assign to variable. The solution should scale to larger list size.
This should work:
main_list = [[1, 2, 3], [4, 5, 6],[7, 8, 9]]
for i in range(len(main_list)):
declare_statement = f'Var{i} = {main_list[i]}'
exec(declare_statement)
'''
now each value of the main_list is stored in variable different variable with
prefix "Var" and index of that value as postfix
'''
That means print(Var0) would display [1, 2, 3], print(Var1) would display [4, 5, 6] and so on but honestly I don't see a point to this.
You could've achieved the same thing by print(main_list[0]) and print(main_list[1]) it is just a waste of memory to assign each value of a list to a variable and it also defeats the purpose of lists and arrays.

How to change the index in a list of lists

I would like to change the way a list of lists in indexed.
Suppose my initial list is two lists of one list and two lists of three elements. For example:
L = [[[1, 2, 3]], [[4, 5, 6], [7, 8, 9]]]
Then let say I want to take '4' in L, I must do
L[1][0][0].
Now I'd like to create a new list such that the last indexing become the first one
Lnew = [[[1], [4, 7]], [[2], [5, 8]], [[3], [6, 9]]]
And then for taking '4' I have to do:
Lnew[0][1][0]
In a more general case, I'd like to create the list Lnew defined by:
Lnew[i][k][l] = L[k][l][i]
Is there a way to do this kind of permutation of the index without doing the following loops:
Lnew = []
for i in range(len(Payment_dates)):
L1 = []
for k in range(N+1):
L2 = []
for l in range(k+1):
L2.append(L[k][l][i])
L1.append(L2)
Lnew.append(L1)
Which is not very optimal in term of complexity.
Thanks
What you'd like to achieve, presupposes that all sublists have the same length.
If they have differing lengths, you may wish to append zeros to all sublists until they have the length of the longest sublist or (which is easier) until infinity.
The same behaviour can be achieved by using a function to access the elements of the list. You can call this function during runtime every time you need an element of the list:
def getElement(myList, i, k, l):
if k < myList.length and l < myList[k].length and i < myList[k][l].length:
return myList[k][l][i]
else:
return None # or zero, or whatever you prefer
Depending on your code structure, you might not need this as a function and you can just put the conditions inside of your code.
You can also nest the if-conditions and throw different errors or return different values depending on what level the element does not exist.
If we neglect the time complexity of outputting a multidimensional list's element, this approach should decrease your time complexity from O(n^3) to O(1).

Create List from Elements of Tuples with Exclusion

I want to make a list of items from the elements of tuples in a list such that those elements don't belong to some other list, and I know that each tuple contains one element from the list I don't want it to belong to and one element that's not in that list. For example, with
tuples = [(2,1), (1,4), (1,7), (3,10), (4,3)]
exclude = [1, 3]
I am looking to create the list
[2, 4, 7, 10]
This is easy enough to accomplish in a clumsy for loop, but it seems like there's a more pythonic way using some function or list comprehension. Any ideas?
Didn't actually understand the question. Assuming this may be you want
>>>list(set([j for i in tuples for j in i if not j in exclude]))
[2, 4, 10, 7]
Assuming your requirement is to convert list of tuples to a list and then getting unique elements in the list, exclusing the list exclude and then sorting them.
from itertools import chain
tuples_final = sorted(list(set(chain(*tuples))-set(exclude)))
You forgot a 4 in your example, the code will return :
>>>[num for tup in tuples for num in tup if num not in exclude]
[2, 4, 7, 10, 4]

Appending correctly with ranges python

This is part of a code for transposing matrixes, the function takes one argument, a list of lists. Let's suppose if input is:
[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
Basically, the output should return
[[1, 4, 7],
[2, 5, 8],
[3, 6, 9]]
And so on for any matrix.
This following code returns
def matrix(data)
column = len(data)
transposed[0].append(data[0][0])
transposed[0].append(data[1][0])
transposed[0].append(data[2][0])
outputs [1,4,7]
However, when I try to make it follow colum length it returns instead
transposed[0].append(data[0:column][0])
outputs [1,2,3]
What is wrong with my code?
You can transpose a matrix using the built-in function zip:
def transpose(m):
return zip(*m)
From the docs:
This function returns a list of tuples, where the i-th tuple contains
the i-th element from each of the argument sequences or iterables. The
returned list is truncated in length to the length of the shortest
argument sequence. When there are multiple arguments which are all of
the same length, zip() is similar to map() with an initial argument of
None. With a single sequence argument, it returns a list of 1-tuples.
With no arguments, it returns an empty list.
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).
To make this return a list of lists instead of a list of tuples, return the following list comprehension:
[list(r) for r in zip(*m)]
Here's how to do it using append:
def transpose(m):
transposed = [[] for _ in range(len(m[0]))]
for i in range(len(m)):
for j in range(len(m[0])):
transposed[j].append(m[i][j])
return transposed
As you can see, using zip is much easier. :)

Categories