I want to return the diagonals i.e. from left to right and from right to left in a given matrix, Im using list comprehensionsto do so but I came up, in my eyes with a to complicated comprehension that returns the left to right matrix.
I was wondering if there are simpler ways to write a comprehension that returns the right to left diagonal ? Also, given that im a noob, im only beginning to dive into learning the language, i was wondering if the right_left comprehension is even conventional ?
matrix = [[1,2,3],
[4,5,6],
[7,8,9]]
left_right = [arr[i][i]
for i in range(len(arr))]
right_left = [arr[i][[-j
for j in range(-len(arr)+1,1)][i]]
for i in range(-len(arr),0)]
left_right = [arr[i][-(i+1)] for i in range(len(arr))]
For explanation of negiative indicies read this: https://stackoverflow.com/a/11367936/8326775
[list(reversed(matrix[i]))[i] for i in range(len(matrix))]
# more transparent version:
for i in range(len(matrix)):
row = list(reversed(matrix[i]))
el = row[i]
print("reversed row {} = {} -> extract element {} -> gives {}".format(i, row, i, el))
#reversed row 0 = [3, 2, 1] -> extract element 0 -> gives 3
#reversed row 1 = [6, 5, 4] -> extract element 1 -> gives 5
#reversed row 2 = [9, 8, 7] -> extract element 2 -> gives 7
You're probably better off learning about numpy, which has a function for diagonals built-in
>>> import numpy as np
>>> matrix = np.array([[1,2,3],
[4,5,6],
[7,8,9]])
>>> np.diag(matrix)
array([1, 5, 9])
>>> np.diag(matrix, k=1)
array([2, 6])
>>> np.diag(matrix, k=-1)
array([4, 8])
Related
I am completetly new to IPython hence I am sorry in case this is totally obvious:
import IPython.display as ipd
import scipy
from scipy import signal as sp
import math
import numpy as np
I defined two functions which should help me generate chords:
def f_k(f_0, k):
return f_0*2**((k%12)/12)
def h_k(k, f0, t):
return math.sin(2*math.pi*f_k(f0, k)*t)
F = 44000
T = 2
f0 = 440
N = F*T
I define H0:
H0 = []
for k in [0,4,7]:
H0.append([h_k(k, f0, t) for t in np.linspace(0, T, N)])
ipd.Audio(H0, rate=F)
and it plays 2 seconds as expected because of the discretization through linspace.
I defined a few several chords and I wanted to concat the lists to get several chords (I expected the sound to be 8 secs long)
H5 = []
for k in [5,9,12]:
H5.append([h_k(k, f0, t) for t in np.linspace(0, T, N)])
H7 = []
for k in [7, 11, 14]:
H7.append([h_k(k, f0, t) for t in np.linspace(0, T, N)])
H9 = []
for k in [5,9,16]:
H9.append([h_k(k, f0, t) for t in np.linspace(0, T, N)])
added_sample = []
for h in [H0, H7, H9, H5]:
added_sample += h
ipd.Audio(added_sample, rate=F)
Yet the sound is somehow 2secs long. Could someone explain how to add chords insted of 'layering' them? Any hint would be greatly appreciated!
Maybe this small example will help you see the different between append and +=:
For each we run:
In [54]: alist = [1,2,3]; blist = [4,5]
append adds one item to the list:
In [55]: alist.append(blist); alist
Out[55]: [1, 2, 3, [4, 5]]
+= is a list join:
In [57]: alist += blist; alist
Out[57]: [1, 2, 3, 4, 5]
and is the equivalent of extend:
In [59]: alist.extend(blist); alist
Out[59]: [1, 2, 3, 4, 5]
The non-in-place version of extend:
In [61]: alist + blist
Out[61]: [1, 2, 3, 4, 5]
Find overlap which given list, a list of intervals like [2, 4], returns whether any two intervals overlap. Boundary overlaps don't count.
Example:
`>>> check_overlap(li=[[1,5], [8,9], [3,6]])
True
>>> check_overlap(li=[[1,5], [5,6]])
False`
data= [[1, 5], [8, 9], [3, 6]]
values = [[value for value in range(elem[0], elem[1])]for elem in data]
print(values)
[[1, 2, 3, 4], [8], [3, 4, 5]]
After that i want to know how to check with each element in a list whether any two intervals overlapping.
For checking the overlap, I would sort the bigger list with first element of the sublists, and check the 2nd element of a sublist is bigger than the 1st element of the next sublist.
def overlap(li):
li.sort(key=lambda x: x[0])
for i in range(len(li)-1):
if li[i][1] > li[i+1][0]:
return True
return False
print(overlap([[1,5], [8,9], [3,6]]))
print(overlap([[1,5], [5,6]]))
True
False
I would use the itertools.combinations function as such:
from itertools import combinations
def check_overlap(li):
lists = [list(range(a, b)) for a, b in li] # Shorter way of your values = ... line
for l1, l2 in combinations(lists, 2):
if any(l in l2 for l in l1):
return True
return False
The combinations(lists, 2) call gives you all possible unique combinations of different elements.
Next, the any() function takes any iterable and returns True if any of the elements in the iterable are True (or rather 'truthy'). In this case, the l in l2 for l in l1 is a generator expression, but would work the same with square brackets around it to explicitly make it into a list first.
You can create sets and check for intersection -
data= [[1, 5], [8, 9], [3, 6]]
sets_from_data = [set(range(*l)) for l in data]
intersection_exists = bool(max([len(a.intersection(b)) for a in sets_from_data for b in sets_from_data if a != b]) > 0)
intersection_exists
# True
If you only have integers you can indeed use range to do this test:
def check_overlap(li):
ranges = [range(r[0]+1, r[1]-1) for r in li]
return any(any(e-1 in r for r in ranges) for l in li for e in l)
On the other hand, if you have floating point values you'll have to tests both bounds of the interval individually (using < and >):
def is_in_range(value, boundaries):
m, M = boundaries
return value > m+1 and value < M-1
def check_overlap(li):
return any(any(is_in_range(e, r) for r in li) for l in li for e in l)
So im pretty new to programming so sorry for my relatively very low understanding of python in general.
Say i have 2 lists, A and B.
If in some case i need to add numbers between 2 lists, each number adding to the number in the same position in the second list. Is there any simple way of doing so?
Eg. A = [1, 2, 3] B = [4, 5, 6]
so C = [1+4, 2+5, 3+6]
All I thought of so far being pretty tired is just adding the 2 but it just makes a list of items from A, followed by items from B
A = [1, 2, 3]
B = [4, 5, 6]
C = A + B
I'm trying to get C = [5, 7, 9] but it ends up being C = [1, 2, 3, 4, 5, 6]
I understand why this would be but being new to this i have no clue of how to do this properly
With that, you are concatenating the two lists, not performing element-wise addition. To do what you have to do, you have a few different options. This is my preferred method:
from operator import add
list(map(add, A, B))
A list comprehension would also work:
[sum(x) for x in zip(A, B)]
Using numpy will also work.
import numpy as np
A = [1, 2, 3]
B = [4, 5, 6]
C = (np.array(A) + np.array(B)).tolist()
I need help with python. (and please excuse my English)
I have an order of list: from [0,1,2,3,4,5] to [5,4,3,2,1,0] (this is kind of an alphabetic order with the "letters" 0, 1 , 2 , 3 ,4 and 5). For example what follows [0,1,2,3,4,5] is [0,1,2,3,5,4], then it's [0,1,2,4,3,5] and it goes on. Be careful you have to use each letter once to form a list.
And basically my program give me a list such as [1,5,0,3,4,2] and I would like to have the corresponding number in my order.
Find this out and I you will save my day ! Thanks :)
I think you have permutations, and need the index:
>>> from itertools import permutations
>>> L = list(permutations(range(6),6)) # Generate the list
>>> len(L)
720
>>> L[0] # First item
(0, 1, 2, 3, 4, 5)
>>> L[-1] # Last item
(5, 4, 3, 2, 1, 0)
>>> L.index((0,1,2,3,4,5)) # Find a sequence
0
>>> L.index((5,4,3,2,1,0))
719
>>> L.index((1,5,0,3,4,2))
219
Note the list as generated is a list of tuples, not list of lists. If you want list of lists:
>>> L = [list(x) for x in permutations(range(6),6)]
>>> L.index([1,5,0,3,4,2])
219
So I have a list of python formatted like:
x = ['[1,2,3]', '[4,5,6,]', ...]
Is there a way to convert the "inner lists" to actual lists? So the output would be
x = [[1,2,3], [4,5,6], ....]
Thanks!
Another example with json:
>>> import json
>>> x = ['[1,2,3]', '[4,5,6]']
>>> [json.loads(y) for y in x]
[[1, 2, 3], [4, 5, 6]]
Please limit your strings to dicts and lists only.
You can use ast.literal_eval for this kind of conversion. You can use map to apply the conversion to each element of your list.
from ast import literal_eval
x = ['[1,2,3]', '[4,5,6,]']
x = map(literal_eval, x)
print x
gives
[[1, 2, 3], [4, 5, 6]]
You can use eval to evaluate strings as code.
x = ['[1,2,3]', '[4,5,6,]']
y = [eval(s) for s in x]