Nested loop list comprehension - python-3.x

How do I write the code below in a list comprehension style?
Residual = np.zeros((noRows, noRows))
Dist = np.zeros((noRows, noRows))
for i in range(noRows):
for j in range(noRows):
Residual[i][j] = (data[data.columns[2]][i]-data[data.columns[2]][j])**2
Dist[i][j] = (data[data.columns[0]][i]-data[data.columns[1]][j])**2

We don't have full code, but from what I can see from your snippet, solution should be something like this:
Residual = [(data[data.columns[2]][i]-data[data.columns[2]][j])**2 for i in range(noRows) for j in range(noRows)]
Dist = [(data[data.columns[0]][i]-data[data.columns[1]][j])**2 for i in range(noRows) for j in range(noRows)]
For example:
noRows = 5
l = [i+j for i in range(noRows) for j in range(noRows)]
print(l)
Output will be:
[0, 1, 2, 3, 4, 1, 2, 3, 4, 5, 2, 3, 4, 5, 6, 3, 4, 5, 6, 7, 4, 5, 6, 7, 8]
Press any key to continue . . .
In your case the statement will be way more complicated compared to "i+j" operation.... but list comprehension should be right.

Related

How to append item to match the length of two list in Python

I am working on a Python script which is connected to a server. Every x min, server returns two list but the length of these list is not same. For ex:
a = [8, 10, 1, 34]
b = [4, 6, 8]
As you can see above that a is of length 4 and b is of length 3. Similarly, sometimes it returns
a = [3, 6, 4, 5]
b = [8, 3, 5, 2, 9, 3]
I have to write a logic where I have to check if length of these two list is not same, then add the 0 at the end of the list which is smaller than other list. So for ex, if input is:
a = [3, 6, 4, 5]
b = [8, 3, 5, 2, 9, 3]
then output will be:
a = [3, 6, 4, 5, 0, 0]
b = [8, 3, 5, 2, 9, 3]
What can I try to achieve this?
def pad(list1, list2):
# make copies of the existing lists so that original lists remain intact
list1_copy = list1.copy()
list2_copy = list2.copy()
len_list1 = len(list1_copy)
len_list2 = len(list2_copy)
# find the difference in the element count between the two lists
diff = abs(len_list1 - len_list2)
# add `diff` number of elements to the end of the list
if len_list1 < len_list2:
list1_copy += [0] * diff
elif len_list1 > len_list2:
list2_copy += [0] * diff
return list1_copy, list2_copy
a = [3, 6, 4, 5]
b = [8, 3, 5, 2, 9, 3]
# prints: ([3, 6, 4, 5, 0, 0], [8, 3, 5, 2, 9, 3])
print(pad(a, b))
a = [8, 10, 1, 34]
b = [4, 6, 8]
# prints: ([8, 10, 1, 34], [4, 6, 8, 0])
print(pad(a, b))
For now, I can suggest this solution:
a = [3, 6, 4, 5]
b = [8, 3, 5, 2, 9, 3]
# Gets the size of a and b.
sizeA, sizeB = len(a), len(b)
# Constructs the zeros...
zeros = [0 for _ in range(abs(sizeA-sizeB))]
# Determines whether a or b needs to be appended with 0,0,0,0...
if sizeA < sizeB:
a += zeros
else:
b += zeros
print(a,b)
You should use extend instead of append. This is the way to add a list to another list in Python. The list here is the list of zeros.
a = [3, 6, 4, 5, 9, 3]
b = [8, 3, 5, 2]
lenA, lenB = len(a), len(b)
diff=abs(len(a)-len(b))
if lenA < lenB:
a.extend([0]*diff)
else:
b.extend([0]*diff)
print(a)
print(b)
You could also try to use more_itertools padded() method:
It's prob. more elegant and adaptable for future Use cases.
Notes: just need to do pip install more_itertools first.
# simple example to demo it:
from more_itertools import padded
print(list(padded([1, 2, 3], 0, 5))) # last num: 5 is the numbers of 0 to be padded to make the total length to be 5. (needs 2 zeros)
# [1, 2, 3, 0, 0]
# more examples:
>>> L = [1, 2, 3]
>>> K = [3, 4, 5, 6, 8, 9]
>>> gap = len(K) - len(L)
# 3
# shorter list is L
>>>list(padded(L, 0, len(L) + gap))
[1, 2, 3, 0, 0, 0]

Repetitive sequence (optimization)

I try to solve this problem:
initial list = [0, 1, 2, 2]
You get this sequence of numbers [0, 1, 2, 2] and you need to add every time the next natural number (so 3, 4, 5, etc.) n times, where n is the element of its index. For example, the next number to add is 3, and list[3] is 2, so you append [3] 2 times. New list will be: [0, 1, 2, 2, 3, 3]. Then the index of 4 is 3, so you have to append 4 three times. The list will be [0, 1, 2, 2, 3, 3, 4, 4, 4] and so on. ([0, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10])
In order to solve this, I tried various approaches. I used recursion, but a recursive approach is very slow in this case. I tried as well the mathematical formula from OEIS (A055086) => a(n) = ceiling(2*sqrt(n+1)) - 2. The problem with the formula is that after 2 ** 20 it is too imprecise.
So, my next idea was to use memoization:
lst = [0, 1, 2, 2]
from itertools import repeat
def find(n):
global lst
print(lst[-1], n, flush = True)
if len(lst) > n:
return lst[n]
for number in range(lst[-1]+1, n+1):
lst += list(repeat(number, lst[number]))
if len(lst) > n:
return lst[n]
Now, this approach works until 2 ** 37, but after this is just timing out. The site where I try to implement my algorithm is (https://www.codewars.com/kata/5f134651bc9687000f8022c4/train/python). I don't ask for a solution, but for any hint on how to optimize my code.
I googled some similar problems and I found that in this case, I could use the total sum of the list, but is not very clear to me yet how could this help me.
Any help is welcomed!
You can answer it iteratively like so:
def find(n):
lst = [0,1,2,2]
if n < 4:
return lst[n]
to_add = 3
while n >= len(lst):
for i in range(lst[to_add]):
lst.append(to_add)
to_add += 1
return lst[n]
You could optimise for large n by breaking early in the for loop, and by keeping track of the list length separately, rather than calls to len

How to find missing numbers from list in Python?

lst = [1, 4, 5, 9, 6]
How to write a code to get some missing values which must return [2, 3, 7, 8]?
Here is my code
new_list = []
for i in range(1, len(lst1)):
if i not in lst1:
new_list.append(i)
print(new_list)
You can convert them to sets and use "-" to calculate the difference. Note that the order is important.
You need to define what you want to compare your list to if you want to find the missing elements. You can automatically do this if it is simple like "the numbers from 1 to 10" using the code:
list(range(1, 10))
The comparison code is:
lst1 = [1, 4, 5, 9, 6]
lst2 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
out = list(set(lst2) - set(lst1))
print(out)
which returns
[8, 2, 3, 7]
It isn't clear exactly what you want from your question, if you give a more detail it will be easier to help.

What does a list next to a list mean?

I am confused about what does lists[outer_index][inner_index] do? I thought that when two lists are next to each other, it means the first list is the selected list and the second list indicates the index of the first list. However, that doesn't seem to be the case here.
def flatten(lists):
results = []
for outer_index in range(len(lists)): # outer index = 0, 1
for inner_index in range(len(lists[outer_index])): # inner_index = [0, 1, 2, 0, 1, 2, 3, 4, 5]
results.append(lists[outer_index][inner_index])
return results
n = [[1, 2, 3], [4, 5, 6, 7, 8, 9]]
print(flatten(n))
You are creating an list of lists (basically a table).
n = [[1, 2, 3],
[4, 5, 6, 7, 8, 9]]
If I do n[0][1] I am saying go to row 0 and grab the element in column 1.
Its better to think of it this way.
n = [[1, 2, 3], [4, 5, 6, 7, 8, 9]]
s = n[0] # Now s = [1,2,3], the first element in n
s[1] = 2 # Because I just grabbed the second element in [1,2,3]
# This is the same as
n[0][1]

How to sum an output in Python

The program below will create a list of 100 numbers chosen randomly between 1-10. I need help to then sum the list, then average the list created.
I have no idea how to begin and since I'm watching videos online I have no person to turn to. I'm very fresh in this world so I may just be missing entire ideas. I would doubt that I don't actually know enough though because the videos I paid for are step by step know nothing to know something.
Edit: I was informed that what the program does is overwrite a variable, not make a list. So how do I sum my output like this example?
This is all I have to go on:
Code:
import random
x=0
while x < 100:
mylist = (random.randrange(1,10))
print(mylist)
x = x+1
I think the shortest and pythonic way to do this is:
import random
x = [random.randrange(1,10) for i in range(100)] #list comprehension
summed = sum(x) #Sum of all integers from x
avg = summed / len(x) #Average of the numbers from x
In this case this shouldn't have a big impact, but you should never use while and code manual counter when you know how many times you want to go; in other words, always use for when it's possible. It's more efficient and clearer to see what the code does.
def sum(list):
sm = 0
for i in list:
sm+=i
return sm
Just run sum(list) to get sum of all elements
Or you can use
import random
x=0
mylist = []
sm = 0
while x < 100:
mylist.append(random.randrange(1,10))
sm += mylist[x]
x += 1
Then sm will be sum of list
The code is not correct. It will not create a list but generate a number everytime. Use the below code to get your desired result.
import random
mylist = []
for x in range(100):
mylist.append(random.randrange(1,10))
print(mylist)
print(sum(mylist))
OR
import random
mylist = [random.randrange(1,10) for value in range(100)]
print(mylist)
print(sum(mylist))
Output:
[3, 9, 3, 1, 3, 5, 8, 8, 3, 3, 1, 2, 5, 1, 2, 1, 4, 8, 9, 1, 2, 2, 4,
6, 9, 7, 9, 5, 4, 5, 7, 7, 9, 2, 5, 8, 2, 4, 3, 8, 2, 1, 3, 4, 2, 2,
2, 1, 6, 8, 3, 2, 1, 9, 6, 5, 8, 7, 7, 9, 9, 9, 8, 5, 7, 9, 4, 9, 8,
7, 5, 9, 2, 6, 8, 8, 3, 4, 8, 4, 7, 9, 9, 4, 2, 9, 9, 6, 3, 4, 9, 5,
3, 8, 4, 1, 1, 3, 2, 6]
512

Resources