Advanced List Comprehension: Creating Averages
I have a list, each element in the list in a list containing 2 numbers separated by a comma.
I have to treat the first items in each list in relation with each other, same with the second ones.
Given a list, I have to replace the first number of each nested list with the average of the number, the first number in the list to its right and the first number in the list to its left. same to the second number. For the first nested list, I have to replace it the average or the number itself and its matching number in the list to its right. For the last, the same with the list to its left.
For example:
[[1, 1], [7, 7], [20, 20], [9, 9], [-12, -12]]
would be:
[[(1+7)/2, (1+7)/2], [(7+1+20)/3, (7+1+20)/3], [(20+7+9)/3, (20+7+9)/3], [(9+20-12)/3, (9+20-12)/3], [(-12+9)/2, (-12+9)/2]]
and thus:
[[4, 4], [9, 9], [12, 12], [5, 5], [-2, -2]]
because we are returning ints.
I have a code but it only prints the average, which is kind of clunky. Please help me to point me to the right direction on how to calculate the elements, and create the new list.
Also, I would like to use only loops and basic list comprehensions, so I can understand the logic.
This is my code so far:
def lpf(lst):
for i in range(len(lst)):
for j in range(2):
if i == 0:
lst[i][j] = int((lst[i][j] + lst[i+1][j]) / 2)
elif 0 < i < (len(lst) - 1):
lst[i][j] = int((lst[i-1][j] + lst[i][j] + lst[i+1][j]) / 3)
elif i == len(lst) - 1:
lst[i][j] = int((lst[i-1][j] + lst[i][j]) / 2)
return lst
And we have to assume the items in the list won't always be the same.
I seem to understand my code's problem - Once I change the first element, the next iteration happens over the new element and not the original. Yet I cant think about how to solve this.
Answer
You wanted list-comprehension, I give you list-comprehension:
[[sum(s[p] for s in l[i-1 if i > 0 else 0:i+2])//(2 if i in (0,len(l)-1) else 3) for p in range(2)] for i in range(len(l))]
In all serious though, I would recommend breaking this down into a for-loop which contains the inner list-comprehension as it is just so unreadable.
Example of it working:
>>> l = [[1, 1], [7, 7], [20, 20], [9, 9], [-12, -12]]
>>> [[sum(s[p] for s in l[i-1 if i > 0 else 0:i+2])//(2 if i in (0,len(l)-1) else 3) for p in range(2)] for i in range(len(l))]
[[4, 4], [9, 9], [12, 12], [5, 5], [-2, -2]]
Exploded form without list-comprehensions:
output = []
for i in range(len(l)):
if i == 0:
group = l[i:i+2]
averaged = [(group[0][0] + group[1][0])//2,
(group[0][1] + group[1][1])//2]
output.append(averaged)
elif i == len(l)-1:
group = l[i-1:i+1]
averaged = [(group[0][0] + group[1][0])//2,
(group[0][1] + group[1][1])//2]
output.append(averaged)
else:
group = l[i-1:i+2]
averaged = [(group[0][0] + group[1][0] + group[2][0])//3,
(group[0][1] + group[1][1] + group[2][0])//3]
output.append(averaged)
which gives output
as before:
[[4, 4], [9, 9], [12, 12], [5, 5], [-2, -2]]
Related Questions
- → What are the pluses/minuses of different ways to configure GPIOs on the Beaglebone Black?
- → Django, code inside <script> tag doesn't work in a template
- → React - Django webpack config with dynamic 'output'
- → GAE Python app - Does URL matter for SEO?
- → Put a Rendered Django Template in Json along with some other items
- → session disappears when request is sent from fetch
- → Python Shopify API output formatted datetime string in django template
- → Can't turn off Javascript using Selenium
- → WebDriver click() vs JavaScript click()
- → Shopify app: adding a new shipping address via webhook
- → Shopify + Python library: how to create new shipping address
- → shopify python api: how do add new assets to published theme?
- → Access 'HTTP_X_SHOPIFY_SHOP_API_CALL_LIMIT' with Python Shopify Module