Reputation: 31
I have a list (fullList) [5, 8, 9, 10, 5, 9, 10, 11, 8, 9, 13, 14, 9, 10, 13, 15, 10, 11, 14, 15] and a value n, - I would like to iterate the first (n) 4 values, then skip 1 number, then iterate the next 4-1 value, and skip 2 numbers, then iterate the next 4-2 numbers and skip 3 numbers, etc... until the list is fully iterated.
My final answer should look like this:
[5,8,9,10,9,10,11,13,14,15]
It can be obtained by taking the first 4 values (5,8,9,10), then skipping 1 count (5), then take the next 3 values (9,10,11) and skipping 2 counts (8,9), then taking the next 2 values (13,14) and skipping 3 counts (9,10,13), taking the next value (15) and skipping 4 counts (10,11,14,15)
--
Edit: I have obtained fullList from iterating the values of a smaller list (listb) [2,3,6,7,8] by adding it against itself. I have solved this part, but still would like to understand the first part (above).
I would like to achieve the following results:
2+3 = 5
2+6 = 8
2+7 = 9
2+8 = 10
3+6 = 9
3+7 = 10
3+8 = 11
6+7 = 13
6+8 = 14
7+8 = 15
Thank you!
Upvotes: 2
Views: 743
Reputation: 48
Personally I think using itertools makes it more complex than it needs to be. This solution should work.
new_list = []
index = 0
i = 0
while(index<len(fullList)):
new_list.extend(fullList[index:index+(n-i)])
index+=(n+1)
i+=1
Edit
fullList = [5, 8, 9, 10, 5, 9, 10, 11, 8, 9, 13, 14, 9, 10, 13, 15, 10, 11, 14, 15]
new_list = []
index = 0
i = 0
n = 4
while(index<len(fullList)):
new_list.extend(fullList[index:index+(n-i)])
index+=(n+1)
i+=1
print(new_list)
#[5, 8, 9, 10, 9, 10, 11, 13, 14, 15]
Upvotes: 0
Reputation: 241821
OK, since this seems to have turned into a kind of golfing contest, here's mine:
def upper_left(arr, n):
"""Arguments:
arr is an iterator returning a flattened n x n array.
Since no element is selected from the last row, it can be
just for the first n-1 rows.
Returns:
An iterator which produces the flattened upper-left triangle
of arr, excluding the anti-diagonal.
"""
return (z for z, (i, j) in zip(arr, ((i,j)
for i in range(n)
for j in range(n)))
if i + j < n - 1)
print(list(upper_left(
[
5, 8, 9, 10, 5,
9, 10, 11, 8, 9,
13, 14, 9, 10, 13,
15, 10, 11, 14, 15
], 5)))
This zips the array against the corresponding row/column indices, and then selects the elements for which the indices are above and to the left of the anti-diagonal (that is, the diagonal from the lower-left corner to the upper-right corner).
Running the above file produces:
$ python upper_left.py
[5, 8, 9, 10, 9, 10, 11, 13, 14, 15]
It would arguably be easier to combine the selection of elements with the generation of the elements in the first place. But this function composes well. (It's probably worth writing the functions which produce the other triangles. The only difference is the comparison in the last line of the function.
Upvotes: 0
Reputation: 11
Well, I made it in 2 different ways:
The first one iterates list element by element with 2 separate counters, the skip counter and the array number counter (counter), when the counter gets fill to the n number (counter == n), it gets into a for loop and starts poping out of the main list the elements (skipping the future iterations as you told us you want to do), when the counterSkip gets to 0, it resets all the counters, reduces the n variable by 1 and increments the number of numbers you want to skip by one (skipN) until the array is full iterated
counter = 0
n= 4
skipN = 1
counterSkip = skipN
array = [5, 8, 9, 10, 5, 9, 10, 11, 8, 9, 13, 14, 9, 10, 13, 15, 10, 11, 14, 15]
for index in enumerate(array):
if counter >= n and counterSkip != 0:
for i in range(counterSkip):
array.pop(index[0])
counterSkip -= 1
n -= 1
skipN += 1
counter = 0
counterSkip = skipN
counter += 1
print(array)
#
[5, 8, 9, 10, 9, 10, 11, 13, 14, 15]
And the second way (It's almost identical as one answer here):
Using the extend() method to add elements to a new list setting lower bound of the main list to a var named "index" that updates it's value summing itself to the n var +1 to preserve a continuity in the iteration, and the upper bound of the main list to the index itself minus i, that serves as a accumulator of how many elements you want to skip each iteration.
You can read more about the "extend" method right here: https://www.programiz.com/python-programming/methods/list/extend
newList = []
index = 0
i = 0
n= 4
list = [5, 8, 9, 10, 5, 9, 10, 11, 8, 9, 13, 14, 9, 10, 13, 15, 10, 11, 14, 15]
while(index<len(list)):
newList.extend(list[index:index+(n-i)])
index+=(n+1)
i+=1
print(newList)
#
[5, 8, 9, 10, 9, 10, 11, 13, 14, 15]
Upvotes: 1
Reputation: 87084
Using a nested list comprehension:
from itertools import chain
full_list = [5, 8, 9, 10, 5, 9, 10, 11, 8, 9, 13, 14, 9, 10, 13, 15, 10, 11, 14, 15]
n = 4
list(chain.from_iterable(x[i:] for i,x in enumerate(
[x for x in [full_list[i*n:i*n+n] for i in range(n+1)]])))
# [5, 8, 9, 10, 9, 10, 11, 13, 14, 15]
The nested list comprehension:
[x for x in [full_list[i*n:i*n+n] for i in range(n+1)]]
groups the list into sublists of n
elements. The outer list comprehension then extracts from those sublists, further sublists of the required length using enumerate()
to determine the start offset.
Finally itertools.chain.from_iterable()
is used to flatten the sublists into a single list as required.
Upvotes: 1
Reputation: 5590
You can use itertools.chain
from itertools import chain
x = [5, 8, 9, 10, 5, 9, 10, 11, 8, 9, 13, 14, 9, 10, 13, 15, 10, 11, 14, 15]
x = list(chain.from_iterable(x[4*idx + idx:4*idx + 4] for idx in range(4)))
For your second part, use itertools.combinations
from itertools import combinations
x = [2,3,6,7,8]
for combo in combinations(x, 2):
a, b = combo
print(f"{a} + {b} = {sum(combo)}")
Upvotes: 1
Reputation: 31
Edit: Ignore the second/alternative part of the question - I managed to get the list that I was looking for
lista = [2,3,6,7,8]
count = 0
originalCount = 0
fullList = []
while count < len(lista):
for j in range(len(lista)):
if (count != j):
if (j > count):
fullList.append(lista[count]+lista[j])
elif (count != originalCount):
j+=count
count+=1
Upvotes: 0