How to get triplets from an array? - python

I have [1,2,3] and I wish to get [(1,1,1), (1,4,9), (1, 8, 27)]. What is the easiest way to achieve this?

I'd probably do this with a list comprehension, an inner loop iterating over your array/list, i. e. [1,2,3] and an outer loop iterating over the powers , i. e. zero, one and two (EDIT: To achieve the output you specified in your question one would need [0,2,3] as powers list):
elements = [1,2,3]
powers = [0,1,2]
[[e**i for e in elements] for i in powers]
The output of this is
[[1, 1, 1], [1, 2, 3], [1, 4, 9]]
If you want a numpy array you can convert it with np.array() and if you want a list of tuples as you have it written in your question convert it with tuple(), i. e.
import numpy as np
elements = [1,2,3]
powers = [0,1,2]
# numpy array
np.array([[e**i for e in elements] for i in powers])
# list of tuples
[tuple([e**i for e in elements]) for i in powers]

I'd do it this way, check it out:
def get_cuadrado_cubo(lista):
resp = []
for i in range (4):
if i == 1:
continue
resp.append((lista [0] ** i, lista [1] ** i, lista [2] ** i) )
return resp

Related

Truncate sublists to the lowest length

I have:
l = [[1,2,3],[3,4],[1,6,8,3]]
I want:
[[1,2],[3,4],[1,6]]
Which is the list l with all sublists truncated to the lowest length found for the sublists in l.
I tried:
min = 1000
for x in l:
if len(x) < min: min = len(x)
r = []
for x in l:
s = []
for i in range(min):
s.append(x[i])
r.append(s.copy())
Which works but quite slow and long to write. I'd like to make this more efficient through list comprehension or similar.
Using del:
n = min(map(len, l))
for a in l:
del a[n:]
You can find the length of each item in the list and then pick min element from it. Later you can use this value to truncate all the items in the list
l = [[1,2,3],[3,4],[1,6,8,3]]
min_length = min(map(len,l)) # using map with len function to get the length of each item and then using min to find the min value.
l = [item[:min_length] for item in l] # list comprehension to truncate the list
One liner -
l = [item[:min(map(len,l))] for item in l]
One fun thing about zip is zip is the inverse itself, so list(zip(*zip(*x))) gives x in similar structure.
And zip stop iteration when any input is exhausted.
Though the results are tuples and the nested lists are not truncated in-place., one can make use of this to build the following output:
Output:
[(1, 2), (3, 4), (1, 6)]
l = [[1, 2, 3], [3, 4], [1, 6, 8, 3]]
print(list(zip(*zip(*l))))
With list comprehension, one-liner:
l = [[1,2,3],[3,4],[1,6,8,3]]
print ([[s[i] for i in range(min([len(x) for x in l]))] for s in l])
Or:
print ([s[:min([len(s) for s in l])] for s in l])
Output:
[[1, 2], [3, 4], [1, 6]]
We compute the minimal length of subslists in the 'range()' to iterate over sublists for that amount and to reconstruct a new subslist. The top-level list comprehension allows to reconstruct the nested sublist.
If you have a large nested list, you should use this version with two lines:
m = min([len(x) for x in l])
print ([[s[i] for i in range(m)] for s in l])
Or:
print ([s[:m] for s in l])
Using zip and preserving the list objects:
print (list([list(x) for x in zip(*zip(*l))]))
Output:
[[1, 2], [3, 4], [1, 6]]

Get ALL items in a python list?

it's very easy to get the number of items in a list, len(list), but say I had a matrix like:
[[1,2,3],[1,2,3]]
Is there a pythonic way to return 6? Or do I have to iterate.
You can use chain
from itertools import chain
l = [[1,2,3],[1,2,3]]
len(list(chain(*l))) # give you 6
the expression list(chain(*l)) give you flat list: [1, 2, 3, 1, 2, 3]
Make the matrix numpy array like this
mat = np.array([[1,2,3],[1,2,3]])
Make the array 1D like this
arr = mat.ravel()
Print length
print(len(arr))
l = [[1,2,3],[1,2,3]]
len([item for innerlist in l for item in innerlist])
gives you 6
You just need to flatten list.
Numpy is the best option.
Still if you want, you can use simple if/else to flatten and return length of list.
Example,
list_1 = [1, 2, 3, 'ID45785', False, '', 2.85, [1, 2, 'ID85639', True, 1.8], (e for e in range(589, 591))]
def to_flatten3(my_list, primitives=(bool, str, int, float)):
flatten = []
for item in my_list:
if isinstance(item, primitives):
flatten.append(item)
else:
flatten.extend(item)
return len(flatten)
print(to_flatten3(list_1))
14
[Program finished]

Pair two lists in inverse order

What I want to do is to choose one item in list A and another one in list B, pair them like:
A[0]+B[n], A[1]+B[n-1],.....,A[n]+B[1]
I use two for loops but it doesn't work:
class Solution(object):
def plusOne(self, digits):
sum=0
for j in range(len(digits)-1,0,-1) :
for i in range(0,len(digits),1):
sum=sum+digits[i]*pow(10,j)
return sum+1
I inputted [1,2,3] and what I want to get is 124,
but I got 661.
Edit:
Sorry, the example I gave above is not so clear.
Let us think about A[1,2,3] and B[6,5,4].
I want output [5,7,9], because 5 is 1+4, 7 is 2+5, 9 is 3+6
What you are trying to do is turn a list of digits into the according number (and add 1). You can enumerate the reversed list in order to pair a digit with its appropriate power of 10:
digits = [1, 2, 3]
sum(10**i * y for i, y in enumerate(digits[::-1])) + 1
# 124
You can apply that to your other example as follows, using zip:
A = [1,2,3]
B = [6,5,4]
sum(10**i * (x+y) for i, (x, y) in enumerate(zip(B, A[::-1])))
# 579
You can do this without a loop:
A = [1,2,3]
B = [6,5,4]
C = list(map(sum,zip(A,B[::-1]) ))
print(C)
zip() - creates pairs of all elements of iterables, you feed it A and B reversed (via slicing). Then you sum up each pair and create a list from those sums.
map( function, iterable) - applies the function to each element of the iterable
zip() works when both list have the same length, else you would need to leverage itertools.zip_longest() with a defaultvalue of 0.
K = [1,2,3,4,5,6]
P = list(map(sum, zip_longest(K,C,fillvalue=0)))
print(P)
Output:
[5, 7, 9] # zip of 2 same length lists A and B reversed
[6, 9, 12, 4, 5, 6] # ziplongest for no matter what length lists
You only need one loop if you want to search in same list back and forth or different list with same length (i and len(lst)-1-i).
Try not use build-ins such as sum, list, tuple, str, int as variable names, it will give you some nasty result in some case.
class Solution(object):
def plusOne(self, digits):
sum_val = 0
for i in range(len(digits)):
sum_val += digits[i]*pow(10, len(digits)-1-i)
return sum_val+1
sol = Solution()
dig = [1, 2, 3]
print(sol.plusOne(dig))
Output:
124
for A = [1, 2, 3] and B = [6, 5, 4].
You can use a list comprehension:
res = [A[i]+B[len(A)-i-1] for i in range(len(A))]
Or the zip() function and a list comprehension:
res = [a+b for (a, b) in zip(A, reversed(B))]
Result:
[5, 7, 9]

How to modify specific item in list of list using list comprehension in python

I am just wondering if there is any better way of modifying the specific item in the list of list using List comprehension?
In below example, I am squaring the second item of each list inside list, but, I don't want to eliminate inner list comprehension.
l = [
[1,2,3,],
[4,5,6,],
[7,8,9,],
]
nl = [[num**2 if i==1 else num for i, num in enumerate(x)] for x in l]
print nl
Not sure how to keep the inner comprehension but you could do something like this:
def square_idx_one(sl):
sl[1] **= 2
return sl
l = [
[1,2,3,],
[4,5,6,],
[7,8,9,],
]
nl = [square_idx_one(sl) for sl in l]
print (nl)
result:
[[1, 4, 3], [4, 25, 6], [7, 64, 9]]
But if you're modifying the original I think a for loop probably edges this solution for performance, not to mention memory
In your case, simply
print [[x, y**2, z] for x, y, z in l]
would do the job and says more explicitly what is going on. In general, do
from itertools import izip
p = (1, 2, 1) # element 0 power 1
# # element 1 power 2
# # element 2 power 1
# ...
print [[x**power for x, power in izip(row, p)] for row in l]

Search in 2D list using python to find x,y position

I have 2D list and I need to search for the index of an element. As I am begineer to programming I used the following function:
def in_list(c):
for i in xrange(0,no_classes):
if c in classes[i]:
return i;
return -1
Here classes is a 2D list and no_classes denotes the number of classes i.e the 1st dimesntion of the list. -1 is returned when c is not in the araray. Is there any I can optimize the search?
You don't need to define no_classes yourself. Use enumerate():
def in_list(c, classes):
for i, sublist in enumerate(classes):
if c in sublist:
return i
return -1
Use list.index(item)
a = [[1,2],[3,4,5]]
def in_list(item,L):
for i in L:
if item in i:
return L.index(i)
return -1
print in_list(3,a)
# prints 1
if order doesn't matter and you have no duplicates in your data, I suggest to turn you 2D list into list of sets:
>>> l = [[1, 2, 4], [6, 7, 8], [9, 5, 10]]
>>> l = [set(x) for x in l]
>>> l
[set([1, 2, 4]), set([8, 6, 7]), set([9, 10, 5])]
After that, your original function will work faster, because search of element in set is constant (while search of element in list is linear), so you algorithm becomes O(N) and not O(N^2).
Note that you should not do this in your function or it would be converted each time function is called.
If your "2D" list is rectangular (same number of columns for each line), you should convert it to a numpy.ndarray and use numpy functionalities to do the search. For an array of integers, you can use == for comparison. For an array of float numbers, you should use np.isclose instead:
a = np.array(c, dtype=int)
i,j = np.where(a == element)
or
a = np.array(c, dtype=float)
i,j = np.where(np.isclose(a, element))
such that i and j contain the line and column indices, respectively.
Example:
a = np.array([[1, 2],
[3, 4],
[2, 6]], dtype=float)
i, j = np.where(np.isclose(a, 2))
print(i)
#array([0, 2])
print(j)
#array([1, 0]))
using list comprehension: (2D list to 1D)
a = [[1,22],[333,55555,6666666]]
d1 = [x for b in a for x in b]
print(d1)

Categories

Resources